summaryrefslogtreecommitdiffstats
path: root/Lib/importlib
diff options
context:
space:
mode:
authorChris Markiewicz <effigies@gmail.com>2024-07-03 20:50:46 (GMT)
committerGitHub <noreply@github.com>2024-07-03 20:50:46 (GMT)
commit94f50f8ee6872007d46c385f7af253497273255a (patch)
treeb8347e9106bcd5129f48af84377531f5772caf16 /Lib/importlib
parente245ed7d1e23b5c8bc0d568bd1a2f06ae92d631a (diff)
downloadcpython-94f50f8ee6872007d46c385f7af253497273255a.zip
cpython-94f50f8ee6872007d46c385f7af253497273255a.tar.gz
cpython-94f50f8ee6872007d46c385f7af253497273255a.tar.bz2
gh-117983: Defer import of threading for lazy module loading (#120233)
As noted in gh-117983, the import importlib.util can be triggered at interpreter startup under some circumstances, so adding threading makes it a potentially obligatory load. Lazy loading is not used in the stdlib, so this removes an unnecessary load for the majority of users and slightly increases the cost of the first lazily loaded module. An obligatory threading load breaks gevent, which monkeypatches the stdlib. Although unsupported, there doesn't seem to be an offsetting benefit to breaking their use case. For reference, here are benchmarks for the current main branch: ``` ❯ hyperfine -w 8 './python -c "import importlib.util"' Benchmark 1: ./python -c "import importlib.util" Time (mean ± σ): 9.7 ms ± 0.7 ms [User: 7.7 ms, System: 1.8 ms] Range (min … max): 8.4 ms … 13.1 ms 313 runs ``` And with this patch: ``` ❯ hyperfine -w 8 './python -c "import importlib.util"' Benchmark 1: ./python -c "import importlib.util" Time (mean ± σ): 8.4 ms ± 0.7 ms [User: 6.8 ms, System: 1.4 ms] Range (min … max): 7.2 ms … 11.7 ms 352 runs ``` Compare to: ``` ❯ hyperfine -w 8 './python -c pass' Benchmark 1: ./python -c pass Time (mean ± σ): 7.6 ms ± 0.6 ms [User: 5.9 ms, System: 1.6 ms] Range (min … max): 6.7 ms … 11.3 ms 390 runs ``` This roughly halves the import time of importlib.util.
Diffstat (limited to 'Lib/importlib')
-rw-r--r--Lib/importlib/util.py4
1 files changed, 3 insertions, 1 deletions
diff --git a/Lib/importlib/util.py b/Lib/importlib/util.py
index 7243d05..8403ef9 100644
--- a/Lib/importlib/util.py
+++ b/Lib/importlib/util.py
@@ -13,7 +13,6 @@ from ._bootstrap_external import spec_from_file_location
import _imp
import sys
-import threading
import types
@@ -257,6 +256,9 @@ class LazyLoader(Loader):
def exec_module(self, module):
"""Make the module load lazily."""
+ # Threading is only needed for lazy loading, and importlib.util can
+ # be pulled in at interpreter startup, so defer until needed.
+ import threading
module.__spec__.loader = self.loader
module.__loader__ = self.loader
# Don't need to worry about deep-copying as trying to set an attribute