Repository navigation
Improve startup time on macOS - #124
Merged
Merged
Conversation
The macOS and Windows packaging jobs resolve "3.12" to the python.org build that ships on the GitHub runners (/usr/local/bin/python3.12) rather than downloading a python-build-standalone interpreter. python.org builds keep the stdlib's C extensions as ~50 separate lib-dynload/*.so files plus libssl and libcrypto, while python-build-standalone compiles them into libpython. That matters on macOS because the onefile binary extracts every shared library into a fresh temp directory on each launch, and the first load of a freshly written Mach-O file costs ~120ms (dyld blocks in fcntl while the kernel runs its first-execution checks). The released v12.7.0 macOS binary loads 49 such files before printing --version. Timing of `isic --version` (hyperfine, 10 runs after 2 warmups, Apple M2 Max, macOS 15.8). Homebrew's Python 3.14 has the same split-stdlib layout as the python.org build and stands in for it: | build | libs loaded | median | mean ± sd | min | max | |-------------------------------------------------|-------------|--------|---------------|-------|-------| | master, Homebrew Python 3.14 (split stdlib) | 51 | 6.51s | 6.50s ± 0.02 | 6.47s | 6.55s | | master, uv-managed Python 3.14 (this change) | 6 | 1.48s | 1.49s ± 0.02 | 1.45s | 1.51s | For reference the released v12.7.0 macOS binary measures 6.3s on the same machine.
charset_normalizer wheels ship two mypyc-compiled extension modules (cd and md) alongside their pure python fallbacks. On macOS, every shared library the onefile binary extracts costs ~120ms on each launch (the first load of a freshly written Mach-O file blocks in dyld while the kernel runs its first-execution checks), and the size of the library barely matters: these two total under 1MB but cost ~240ms in `-X importtime` inside the frozen binary versus ~4ms unfrozen. Installing charset_normalizer from its sdist in the package env gives the pure python modules (the sdist only builds the mypyc extensions when CHARSET_NORMALIZER_USE_MYPYC=1). Only requests uses it, for guessing the encoding of responses without a charset, which isn't on any hot path here. Timing of `isic --version` (hyperfine, 10 runs after 2 warmups, two rounds each, Apple M2 Max, macOS 15.8, uv-managed Python 3.14): | build | libs loaded | median | mean ± sd | min | max | |--------------------------------|-------------|--------|--------------|-------|-------| | previous commit | 6 | 1.53s | 1.55s ± 0.07 | 1.47s | 1.70s | | previous commit, second round | 6 | 1.51s | 1.52s ± 0.04 | 1.46s | 1.61s | | this commit | 4 | 1.23s | 1.23s ± 0.02 | 1.19s | 1.27s | | this commit, second round | 4 | 1.23s | 1.23s ± 0.02 | 1.18s | 1.26s |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.