[feat/precompile-tooling] docs: document the opt-in precompiled mode - #6138
[feat/precompile-tooling] docs: document the opt-in precompiled mode#6138henryiii wants to merge 1 commit into
Conversation
a952ae6 to
8a3b546
Compare
8a3b546 to
9646128
Compare
9646128 to
37431e2
Compare
|
Codex review: 🤖 AI text below 🤖 Precompiled mode fails for consumers using pybind11's configurable namespace via target-specific definitions. Review comment:
|
|
Testing on boost-histogram:
🤖 AI text below 🤖 Done — the precompile mode works here, with a modest but real win. Both builds link, import, and pass tests (168 passed against the precompiled build). Setup (left in the working tree for you to inspect): I pointed the Compile time — every project TU gets faster by a roughly fixed ~0.6–0.9 s (the pybind11 non-template code it no longer compiles):
Project-TU CPU total dropped 37.0 s → 32.1 s (−13%). The one-time pybind11 library adds back ~5.8 s across 7 tiny TUs, so a clean build's total CPU is a wash (49.0 s → 49.4 s); wall time went 30.4 s → 28.9 s (−5%) because the tiny library TUs parallelize freely. The −13% is what you keep on every rebuild after the first, and per-TU savings show up directly in incremental edit–compile loops. Memory — each TU's peak RSS drops ~40–70 MB (e.g. register_algorithm 356 → 292 MB, register_axis 1120 → 1076 MB). The build-wide peak barely moves (register_histograms 1914 → 1878 MB, −2%) since it's dominated by Boost.Histogram template instantiation, not pybind11. Verdict: it does what the pybind11 PR claims — removes a fixed per-TU cost — but boost-histogram's TUs are so template-heavy that the relative gain is small (~13% CPU, ~2% peak memory). The mode would matter more on memory-constrained CI (the small TUs' footprints shrink noticeably) and for projects with many light binding TUs. The binary grew 33 KB, likely because the static library isn't covered by the module's LTO. The |
|
And checking to see if we can enable LTO to get rid of that extra size: 🤖 AI text below 🤖 Yes — it works cleanly. One line in our CMakeLists after if(TARGET pybind11_precompiled)
target_link_libraries(pybind11_precompiled PRIVATE pybind11::lto)
endif()Results for the precompile+LTO variant:
The caveat is portability rather than anything we hit here: with full The edit is in the working tree along with the earlier ones, and the third build tree is at |
🤖 AI text below 🤖 Done. pybind11's precompiled mode (PR #6138 stack) is a clear win for PyTorch's What I set up
MeasurementsA/B by flipping the flag, which rebuilds the identical set of 165
The heaviest pybind11 TUs ( Sanity check: Current state: submodule on |
Assisted-by: ClaudeCode:claude-fable-5
37431e2 to
7fd2c3a
Compare
🤖 AI text below 🤖
Description
Stacked on #6137; final slice of the pre-compilation series. Adds a "Pre-compiling part of pybind11" section to
docs/compiling.rst(CMake keyword/variable/function, config-guard behavior, caveats, and the non-CMake path including a Meson snippet), makes it the first suggestion under the FAQ's "How can I reduce the build time?", and documentspybind11_precompile/pybind11_SRC_DIR/ thePRECOMPILEkeyword in the CMake config docstring.Benchmark (macOS arm64, AppleClang 21, Debug, Ninja, the ~50-TU
pybind11_teststarget; precompile OFF → ON):The per-TU CPU saving is what scales for large projects and CI machines with fewer cores; the earlier slices also showed the precompiled test module shrinking ~1.6 MB in Debug.
Suggested changelog entry:
pybind11_add_module(... PRECOMPILE)/PYBIND11_PRECOMPILEin CMake,Pybind11Extension(precompile=True)in setuptools, andpython -m pybind11 --srcdirplus a pkg-configsrcdirvariable for other build systems. Header-only remains the default.📚 Documentation preview 📚: https://pybind11--6138.org.readthedocs.build/