Repository navigation
Share whole-variable liveness keys and memoize UnionType::hasTemplateOrLateResolvableType() - #6990
Open
ondrejmirtes wants to merge 2 commits into
Open
ondrejmirtes wants to merge 2 commits into
ondrejmirtes wants to merge 2 commits into
Conversation
… set Every write replacing a whole variable observes and kills the read keys of all its slots, and compileAccesses() copied them into each such write: quadratic in the writes and reads of a variable. They are now built once per variable and shared. Removing them, the markers of a variable and the observed keys from the live set walks the smaller of the two sets, like the per-slot markers already did. Amp-Thread-ID: https://ampcode.com/threads/T-01a1ad6c-dec2-72ff-bbe8-5b3b62746c94
TypeUtils::resolveLateResolvableTypes() asks for every resolved type, so an array keyed by a union of thousands of literals scanned the whole union on every assignment. Amp-Thread-ID: https://ampcode.com/threads/T-01a1ad6c-dec2-72ff-bbe8-5b3b62746c94
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.
tests/bench/data/literal-key-union-offset-write.php(1000 ×$b = $a; $b['lN'] = N; echo $b['lN'];with$akeyed by a union of 2000 literals) is the slowest benchmark in the CodSpeed workflow (#6974), at about 13 minutes under the CPU simulation. Two costs that grow with that shape:VariableLivenessResolver(d0b1cf1). Every write that replaces the whole variable observes and kills the read keys of all of its slots.compileAccesses()copied all of them into each such write, so 1000 writes × ~2000 keys of$b. Going backwards over the function, each of those writes then looped over all 2000 kill keys and all 1001 marker slots of$b, while the live set at that point holds only a handful of keys. The keys are now built once per variable and shared, which PHP's copy-on-write makes free. Removing keys and markers from the live set, and matching observed keys against it, now walks the smaller of the two sets, the way the per-slot markers already did.markersByNameholds the markers of all slots of a variable, so a whole-variable write removes them in one pass.UnionType::hasTemplateOrLateResolvableType()(339d009).TypeUtils::resolveLateResolvableTypes()asks this for every resolved type, so every assignment scanned the whole 2000-member key union. It is now memoized in the union, likeisNull()andisCallable().Both commits port their change to the turbo-ext C++ twin, with the regenerated headers (
UnionType.h,TemplateUnionType.h,TemplateBenevolentUnionType.h,VariableLivenessResolver.h).Measurements
Instruction counts from CodSpeed's CPU simulation, using the harness from #6974 on an Amp orb with PHP 8.5.12 (absolute numbers differ slightly from the CI runner's):
Peak memory changes by +0.0 to +0.4 %. Under the simulation, literal-key-union-offset-write now takes 4.3 minutes instead of 6.2 on this machine.
Wall clock:
bin/phpstan analyse --debugon literal-key-union-offset-write, median of 7 interleaved runs per side, result cache and container cleared before each run (about 0.9 s of each run is building the container), no turbo extension. Amp orb, Intel Xeon @ 2.60 GHz, 16 vCPUs, PHP 8.5.12 NTS: 3.70 s → 2.82 s.Checks
make tests, with and without the turbo extension loaded (23,547 tests). Both runs have one failure,OverridingMethodRuleConfigPhpTest::testTentativeReturnTypesInPhpVersionRange, which fails the same way on unchanged 2.3.x.turbo-ext/tests/walk-trace.php: identical (702,499 trace lines).smoke.phpALL OK,signature-parity.phpOK,side-by-side.phpOK.make phpstanand phpcs are clean.