Skip to content

Commit

Permalink
ModuleAccelerator performance: cache the result of checking if a ca…
Browse files Browse the repository at this point in the history
…ller is in the denylist (#15056)

Authors:
  - Ashwin Srinath (https://github.com/shwina)
  - GALI PREM SAGAR (https://github.com/galipremsagar)
  - Lawrence Mitchell (https://github.com/wence-)

Approvers:
  - Vyas Ramasubramani (https://github.com/vyasr)

URL: #15056
  • Loading branch information
shwina authored Apr 9, 2024
1 parent 54eff4e commit 338cc98
Showing 1 changed file with 15 additions and 9 deletions.
24 changes: 15 additions & 9 deletions python/cudf/cudf/pandas/module_accelerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from abc import abstractmethod
from importlib._bootstrap import _ImportLockContext as ImportLock
from types import ModuleType
from typing import Any, ContextManager, Dict, List, NamedTuple
from typing import Any, ContextManager, Dict, NamedTuple, Tuple

from typing_extensions import Self

Expand Down Expand Up @@ -377,7 +377,7 @@ class ModuleAccelerator(ModuleAcceleratorBase):
attempts to call the fast version first).
"""

_denylist: List[str]
_denylist: Tuple[str]
_use_fast_lib: bool
_use_fast_lib_lock: threading.RLock
_module_cache_prefix: str = "_slow_lib_"
Expand Down Expand Up @@ -407,7 +407,7 @@ def __new__(
if mod.startswith(self.slow_lib):
sys.modules[self._module_cache_prefix + mod] = sys.modules[mod]
del sys.modules[mod]
self._denylist = [*slow_module.__path__, *fast_module.__path__]
self._denylist = (*slow_module.__path__, *fast_module.__path__)

# Lock to manage temporarily disabling delivering wrapped attributes
self._use_fast_lib_lock = threading.RLock()
Expand Down Expand Up @@ -551,17 +551,13 @@ def getattr_real_or_wrapped(
# release the lock after reading this value)
use_real = not loader._use_fast_lib
if not use_real:
CUDF_PANDAS_PATH = __file__.rsplit("/", 1)[0]
# Only need to check the denylist if we're not turned off.
frame = sys._getframe()
# We cannot possibly be at the top level.
assert frame.f_back
calling_module = pathlib.PurePath(frame.f_back.f_code.co_filename)
use_real = not calling_module.is_relative_to(
CUDF_PANDAS_PATH
) and any(
calling_module.is_relative_to(path)
for path in loader._denylist
use_real = _caller_in_denylist(
calling_module, tuple(loader._denylist)
)
try:
if use_real:
Expand Down Expand Up @@ -623,3 +619,13 @@ def disable_module_accelerator() -> contextlib.ExitStack:
stack.enter_context(finder.disabled())
return stack.pop_all()
assert False # pacify type checker


# because this function gets called so often and is quite
# expensive to run, we cache the results:
@functools.lru_cache(maxsize=1024)
def _caller_in_denylist(calling_module, denylist):
CUDF_PANDAS_PATH = __file__.rsplit("/", 1)[0]
return not calling_module.is_relative_to(CUDF_PANDAS_PATH) and any(
calling_module.is_relative_to(path) for path in denylist
)

0 comments on commit 338cc98

Please sign in to comment.