Skip to content

docs(performance): re-measure the comparative table for 3.1.0 - #379

Merged
lesnik512 merged 1 commit into
mainfrom
docs/refresh-performance-numbers
Jul 27, 2026
Merged

docs(performance): re-measure the comparative table for 3.1.0#379
lesnik512 merged 1 commit into
mainfrom
docs/refresh-performance-numbers

Conversation

@lesnik512

Copy link
Copy Markdown
Member

The published table was measured 2026-07-17, i.e. against 3.0.0. 3.1.0 changed the top of the resolve path (resolve_provider opens with an inline closed test rather than an unconditional _raise_if_closed() call; build_child_container lost its check entirely), so it needed re-measuring. Bundle: planning/changes/2026-07-27.01-refresh-performance-numbers.md.

Five runs of just bench-compare, median-of-medians per scenario — the methodology the page already states. Rival pins unchanged (dishka 1.10.1, dependency-injector 4.49.1, that-depends 4.0.2, wireup 2.12.0), so this refreshes modern-di's column and the ratios derived from it, not a rival bump.

No verdict changed — nothing crossed 1.0 either way. Ratios moved modestly in modern-di's favour on C1/C2 (vs dependency-injector on C2: 4.58 → 3.93; vs dishka on C1: 1.30 → 1.28) and were flat on C3/C4. Two prose figures were tightened to match: the dishka/wireup construction-heavy range (1.3–1.9x → 1.3–1.8x) and C4-vs-dishka (1.02 → 1.00).

Two things I added rather than left implicit:

  • The machine changed (Apple M2 / CPython 3.14.4 → M4 / 3.14.6), so absolute times drop for the hardware as well as the library — including on C3, which a same-machine guard-tier comparison of 3.0.0 vs 3.1.0 showed did not move. The page now says to compare ratio columns across revisions of the page, not nanoseconds. Without that note the diff reads as a 3.1 speedup on a scenario 3.1 didn't touch.
  • "Why the results look this way" gained the 3.1.0 frame removal, attributed to the guard-suite measurement that isolates it rather than to this cross-machine table.

Guard-tier evidence for that claim, run against the 3.0.0 tag in a scratch worktree in both orderings to rule out thermal drift: g1_transient_resolve −10.9%/−10.9%, g2_cached_resolve −6.6%/−5.3%, g6_build_child_container −8.0%/−5.4%, g6b −13.3%/−7.0%, g14_concurrent_cached_hit −5.5% to −7.4%. Nothing regressed in both orderings, and g3/g4/g9 moved in one ordering only — consistent with their running through compiled resolvers whose guard was already inline on both versions.

Deliberately out of scope, noted in the bundle: bumping rival pins, and publishing the C5/C6 scenarios the comparative suite already runs but this page has never shown.

mkdocs build --strict, just lint-ci and just check-planning all clean. Docs-only; no code touched.

🤖 Generated with Claude Code

Five runs, median-of-medians per scenario, matching the methodology the page
already states. Rival pins unchanged, so this refreshes modern-di's column and
the ratios derived from it. No verdict crossed 1.0; the dishka/wireup range and
the C4-vs-dishka figure were tightened to match.

The measurement machine also changed since the previous publication (M2/3.14.4
to M4/3.14.6), so the page now tells readers to compare ratios across revisions
rather than nanoseconds - C3 dropped in absolute terms on a scenario a
same-machine 3.0.0-vs-3.1.0 guard comparison showed did not move.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Details
Benchmark suite Current: 432d3e7 Previous: 552f7c9 Ratio
benchmarks/test_guard_cold.py::test_g8_cold_first_resolve 19410.05218150231 iter/sec (stddev: 0.0001528287466197493) 20501.106615692996 iter/sec (stddev: 0.0002385664721561687) 1.06
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[1] 317.0368465697806 iter/sec (stddev: 0.00012674853548938375) 319.13347597625176 iter/sec (stddev: 0.00005591225341324346) 1.01
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[2] 301.90532605791867 iter/sec (stddev: 0.00006873769146441019) 323.66904621779076 iter/sec (stddev: 0.00003696035094731032) 1.07
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[4] 284.61648392309587 iter/sec (stddev: 0.00011159300338704306) 295.92740259502506 iter/sec (stddev: 0.0001869359183473183) 1.04
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[1] 1379.7177263098847 iter/sec (stddev: 0.001183510809353734) 1192.8435944970065 iter/sec (stddev: 0.0021649039909886585) 0.86
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[2] 1235.021364994624 iter/sec (stddev: 0.0005545565267556137) 1259.5191174899107 iter/sec (stddev: 0.0006782309481742352) 1.02
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[4] 799.8293430787867 iter/sec (stddev: 0.0014271871767045315) 901.6730904860332 iter/sec (stddev: 0.0007326898557464034) 1.13
benchmarks/test_guard_lifecycle.py::test_g6_build_child_container 479077.40436114086 iter/sec (stddev: 0.000009713386407877722) 430241.96604200284 iter/sec (stddev: 0.00006837067718367991) 0.90
benchmarks/test_guard_lifecycle.py::test_g6b_build_child_container_auto_scope 465203.94237959787 iter/sec (stddev: 0.000009640160385988872) 449558.3357643676 iter/sec (stddev: 0.000010442471120194737) 0.97
benchmarks/test_guard_lifecycle.py::test_g7_request_lifecycle 65773.67836882062 iter/sec (stddev: 0.000013895523963619784) 72758.54678403895 iter/sec (stddev: 0.000013767794611012372) 1.11
benchmarks/test_guard_lifecycle.py::test_g13_teardown_at_scale 41316.00168152066 iter/sec (stddev: 0.000020311608456818122) 40991.403991742496 iter/sec (stddev: 0.000020924421405964968) 0.99
benchmarks/test_guard_resolve.py::test_g1_transient_resolve 1215106.5986841575 iter/sec (stddev: 3.783021624108872e-7) 1244527.708280102 iter/sec (stddev: 6.010381247138101e-7) 1.02
benchmarks/test_guard_resolve.py::test_g2_cached_resolve 2768419.334422337 iter/sec (stddev: 5.912380193291223e-8) 2657837.3355129194 iter/sec (stddev: 6.189431422374186e-8) 0.96
benchmarks/test_guard_resolve.py::test_g3_deep_chain 487986.22515885206 iter/sec (stddev: 5.228600962928496e-7) 488386.7102571147 iter/sec (stddev: 8.87661768896005e-7) 1.00
benchmarks/test_guard_resolve.py::test_g4_wide_resolve 300726.90985739726 iter/sec (stddev: 7.497780766643348e-7) 306260.45783673355 iter/sec (stddev: 6.975007409867451e-7) 1.02
benchmarks/test_guard_resolve.py::test_g5_cross_scope 1053747.4115499174 iter/sec (stddev: 0.0000013166442824700342) 1117644.9044456459 iter/sec (stddev: 4.203654542509246e-7) 1.06
benchmarks/test_guard_resolve.py::test_g9_context_resolve 572841.0425881288 iter/sec (stddev: 5.317916710091668e-7) 426591.3917675563 iter/sec (stddev: 8.729055761643911e-7) 0.74
benchmarks/test_guard_resolve.py::test_g12_override_active_resolve 370346.2948262415 iter/sec (stddev: 4.5237886272696495e-7) 361859.77176196815 iter/sec (stddev: 8.33311541987878e-7) 0.98
benchmarks/test_guard_validate.py::test_g10_validate_deep_chain 26425.659251680732 iter/sec (stddev: 0.000022307176112721742) 26825.449962516916 iter/sec (stddev: 0.00006566129517211644) 1.02
benchmarks/test_guard_validate.py::test_g11_validate_wide 17205.610033690384 iter/sec (stddev: 0.000009380176784368208) 17807.445879545092 iter/sec (stddev: 0.000011790803021058317) 1.03

This comment was automatically generated by workflow using github-action-benchmark.

@lesnik512
lesnik512 merged commit 1e9772b into main Jul 27, 2026
9 checks passed
@lesnik512
lesnik512 deleted the docs/refresh-performance-numbers branch July 27, 2026 14:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant