Repository navigation
refactor: dispatch the dependency graph by provider type, make the provider step a free function (#617) - #629
Merged
Merged
Conversation
…ovider step a free function (#617)
There was a problem hiding this comment.
Benchmark
Details
| Benchmark suite | Current: 368f21f | Previous: 4ff73aa | Ratio |
|---|---|---|---|
benchmarks/test_guard_by_type.py::test_g16_resolve_by_type |
4495303.509188955 iter/sec (stddev: 4.130700358559182e-9) |
2883405.740465237 iter/sec (stddev: 8.889110093741167e-9) |
0.64 |
benchmarks/test_guard_by_type.py::test_g17_resolve_by_type_large_registry |
4393297.28691088 iter/sec (stddev: 1.3655638403767411e-8) |
2855075.2116767764 iter/sec (stddev: 9.309855419546196e-9) |
0.65 |
benchmarks/test_guard_cold.py::test_g8_cold_first_resolve |
23442.736708711625 iter/sec (stddev: 0.000044770248239260135) |
24340.53600966804 iter/sec (stddev: 0.000043030297095546176) |
1.04 |
benchmarks/test_guard_cold.py::test_g8b_cold_first_resolve_cached |
19113.26348828863 iter/sec (stddev: 0.0001384024382391895) |
19087.243953149085 iter/sec (stddev: 0.00013892428205748751) |
1.00 |
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[1] |
547.2620530427952 iter/sec (stddev: 0.00011673943749696228) |
374.0257215909595 iter/sec (stddev: 0.00004170459432905435) |
0.68 |
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[2] |
539.3071860161772 iter/sec (stddev: 0.00009171101100072757) |
357.8080831726214 iter/sec (stddev: 0.00008839544842994853) |
0.66 |
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[4] |
512.7451446978226 iter/sec (stddev: 0.00006790238780643825) |
348.63113879817206 iter/sec (stddev: 0.00009581006421014357) |
0.68 |
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[1] |
15833.42393563162 iter/sec (stddev: 0.000008047411261998512) |
12587.970243286616 iter/sec (stddev: 0.00004275495653516427) |
0.80 |
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[2] |
7084.026830045798 iter/sec (stddev: 0.00002070785777983849) |
6114.5138380448025 iter/sec (stddev: 0.000012780478478524728) |
0.86 |
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[4] |
3732.0970139929277 iter/sec (stddev: 0.0000384159133709794) |
3367.8641378764446 iter/sec (stddev: 0.000041659057409168) |
0.90 |
benchmarks/test_guard_concurrency.py::test_g15b_concurrent_first_resolve_sibling_children[1] |
11109.590743054341 iter/sec (stddev: 0.00000885535957794347) |
9217.86068044916 iter/sec (stddev: 0.00000935387959642552) |
0.83 |
benchmarks/test_guard_concurrency.py::test_g15b_concurrent_first_resolve_sibling_children[2] |
4533.39074621599 iter/sec (stddev: 0.000023146996249073897) |
3934.8513224509657 iter/sec (stddev: 0.00004120578958358568) |
0.87 |
benchmarks/test_guard_concurrency.py::test_g15b_concurrent_first_resolve_sibling_children[4] |
2086.6593088758946 iter/sec (stddev: 0.000040863800307781456) |
1897.565913138107 iter/sec (stddev: 0.000042475565665712956) |
0.91 |
benchmarks/test_guard_concurrency.py::test_g15c_worker_pool_floor_control[1] |
36853.66729283851 iter/sec (stddev: 0.000005471958123528633) |
40008.121648654465 iter/sec (stddev: 0.000006876301252925549) |
1.09 |
benchmarks/test_guard_concurrency.py::test_g15c_worker_pool_floor_control[2] |
14976.862619390235 iter/sec (stddev: 0.00001603582282394068) |
13109.819648304185 iter/sec (stddev: 0.000011772923051481861) |
0.88 |
benchmarks/test_guard_concurrency.py::test_g15c_worker_pool_floor_control[4] |
6191.6523833006 iter/sec (stddev: 0.000033662863947301256) |
5893.357920429329 iter/sec (stddev: 0.000031517902397323976) |
0.95 |
benchmarks/test_guard_lifecycle.py::test_g6_build_child_container |
1743646.023111904 iter/sec (stddev: 2.7825025711581113e-8) |
1589390.3742276558 iter/sec (stddev: 3.008854030860649e-8) |
0.91 |
benchmarks/test_guard_lifecycle.py::test_g6b_build_child_container_auto_scope |
1905100.3775987742 iter/sec (stddev: 1.4413810602939395e-8) |
1655887.5288100082 iter/sec (stddev: 2.6907570556999255e-8) |
0.87 |
benchmarks/test_guard_lifecycle.py::test_g7_request_lifecycle_batch |
3575.4211659568164 iter/sec (stddev: 0.00000777005025252269) |
2998.459393278227 iter/sec (stddev: 0.000011594545473644167) |
0.84 |
benchmarks/test_guard_lifecycle.py::test_g7c_event_loop_floor_control |
68581.74713105979 iter/sec (stddev: 0.0000018825160600172051) |
58320.38401458291 iter/sec (stddev: 0.000002060952743492397) |
0.85 |
benchmarks/test_guard_lifecycle.py::test_g7b_request_cycle_sync |
464318.4396151828 iter/sec (stddev: 9.885483991657149e-8) |
376103.53949892963 iter/sec (stddev: 8.654240798812594e-8) |
0.81 |
benchmarks/test_guard_lifecycle.py::test_g13_teardown_at_scale |
68411.66263972252 iter/sec (stddev: 0.0000011099926786051772) |
57111.16783367965 iter/sec (stddev: 0.0000017513335188553384) |
0.83 |
benchmarks/test_guard_lifecycle.py::test_g13b_teardown_at_scale_async_no_finalizers |
632.2478632783732 iter/sec (stddev: 0.0010776273027091076) |
521.7209230521734 iter/sec (stddev: 0.001402826024751173) |
0.83 |
benchmarks/test_guard_resolve.py::test_g1_transient_resolve |
2373550.2948261104 iter/sec (stddev: 2.3144126754821485e-8) |
2074878.6351624003 iter/sec (stddev: 3.276435272397166e-8) |
0.87 |
benchmarks/test_guard_resolve.py::test_g2_cached_resolve |
4420975.35293048 iter/sec (stddev: 9.588399244779715e-9) |
2967918.0230213017 iter/sec (stddev: 2.0473202345492446e-8) |
0.67 |
benchmarks/test_guard_resolve.py::test_g3_deep_chain |
785110.1812848137 iter/sec (stddev: 6.420811528484894e-8) |
729288.0285512193 iter/sec (stddev: 7.439908147066853e-8) |
0.93 |
benchmarks/test_guard_resolve.py::test_g4_wide_resolve |
513999.85253215564 iter/sec (stddev: 3.984019549565078e-7) |
450713.2954819865 iter/sec (stddev: 4.066462596101566e-7) |
0.88 |
benchmarks/test_guard_resolve.py::test_g5_cross_scope |
2117446.611365043 iter/sec (stddev: 1.5884132457867998e-8) |
1871349.7568507271 iter/sec (stddev: 2.952013145968033e-8) |
0.88 |
benchmarks/test_guard_resolve.py::test_g9_context_resolve |
1649955.3687103158 iter/sec (stddev: 1.7982965377398072e-7) |
1322038.2352682091 iter/sec (stddev: 1.5385006162761187e-7) |
0.80 |
benchmarks/test_guard_resolve.py::test_g12_override_active_resolve |
825841.9830640745 iter/sec (stddev: 2.4990759111447557e-8) |
739381.1830524713 iter/sec (stddev: 6.086383291251184e-8) |
0.90 |
benchmarks/test_guard_resolve.py::test_g18_alias_hop |
4399035.062868196 iter/sec (stddev: 1.1950819248245055e-8) |
2906313.19234593 iter/sec (stddev: 1.5861470107359007e-8) |
0.66 |
benchmarks/test_guard_validate.py::test_g10_validate_deep_chain |
39950.61198811231 iter/sec (stddev: 0.000019565790364117832) |
34731.80562784902 iter/sec (stddev: 0.00002043573443514095) |
0.87 |
benchmarks/test_guard_validate.py::test_g11_validate_wide |
24164.920167221884 iter/sec (stddev: 0.000024852409141282664) |
18375.912926832763 iter/sec (stddev: 0.0002530440259825077) |
0.76 |
This comment was automatically generated by workflow using github-action-benchmark.
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.
Part of #617 (items 7 and 8). Closes #617. No public API change.
Summary
dependency_graphdispatches on the closed provider set by type, the same wayresolver_compilerdoes. The virtual hooks_get_dependencies,_redirect_targetand_iter_validation_issuesare gone fromAbstractProvider,FactoryandAlias;dependency_graphnow hasredirect_targetanddependencies_of, andcollect_errorsreports unwireableFactoryparameters itself._ignores_scopeClassVar added in fix: skip scope checks on Container injection in validate() (#612) #620 is replaced bydependency_chain[-1] is container_provider, so there is one dispatch mechanism instead of two.AbstractProvider._resolution_stepis now the free functionprovider_step(provider, scope=None)inexceptions/rendering.py. Callers that need a zero-argument step bind it withfunctools.partial.Factory._argument_resolution_erroris nowwiring.argument_resolution_error, next toWiringPlan.unwireable.Factoryno longer importssuggester.dependency_graph.pyis rewritten: only importingContainerwould cycle.dependency_graph, which fall through silently.Design decisions
Aliassource is still built in two places:dependencies_offorvalidate(), and the compiled resolver for resolve time. The resolve-time error has to be fresh per call because_prepend_stepmutates it.Factorysubclass now gets no edges and no validation issues. The resolver compiler already rejects subclasses withTypeErrorat first resolve, and the design decisions page documents the provider set as closed.test_validate_memoizes_diamondused aFactorysubclass to count dependency reads; it now monkeypatchesdependency_graph.dependencies_of.Performance
Interleaved A/B against #626 + #628, 14 rounds, paired median (A/A noise is about ±2.5%): G10 build + validate -4.9%; G8 cold +1.5%, inside noise; every other scenario within ±1%.
Test plan
just lint-cijust test-race