Repository navigation
Share the resolved class constant type between the native and PHPDoc passes when the constant has no PHPDoc type - #6968
Merged
Conversation
… when the constant has no PHPDoc type Amp-Thread-ID: https://ampcode.com/threads/T-01a1b134-c96d-73fb-8c38-b7e71e89e58e
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.
Since 9b24ee5 ("Do not use PHPDoc type of overridable class constants as their native type", first in 2.3.3),
getClassConstFetchTypeByReflection()caches the native-types pass under a separate<Class>::<CONST>#nativekey. As a result, a fetch likeself::XorFoo::Xresolves and transforms the constant's initializer twice, once for each pass. For huge constant arrays this costs a lot. Bisecting with instruction counts showed thatbug-12671.php,bug-12159.phpandbug-10538.phpintests/bench/datagot slower at this commit.In this branch (a fetch on a class name, not on an object), the PHPDoc type is the only input that differs between the two passes.
ConstantResolver::resolveClassConstantType()only uses it for adynamicConstantNameslist entry without a native type.Change
getConstantPhpDocType()once.#native, so the second pass hits the cache.turbo-ext/src/InitializerExprTypeResolver.cppgets the identical change.Instruction counts
Net instructions = cachegrind count of the file minus the count of an empty file at the same commit, so PHPStan's boot is excluded. Measured with PHP 8.4.27 at level 8 with bleedingEdge, without the turbo extension.
For reference, on 2f22669, the parent of 9b24ee5, the counts are 10.25 G, 2.83 G and 17.09 G. bug-12671 and bug-10538 are back to that level. The remaining ~0.26 G on bug-12159 comes from later commits, not from 9b24ee5.
Wall-clock times
These are medians of 9 runs after 2 warm-up runs (hyperfine) of
bin/phpstan analyse -c <config> --debug --no-progress <file>on 2.3.x (bcca2b0) and on this branch. The repository has notests/bench/phpstan.neon, so the config is the equivalent oftests/bench/BenchCase.php: it includesconf/bleedingEdge.neonand setslevel: 8andinferPrivatePropertyTypeFromConstructor: true.Machine: Amp orb (E2B sandbox), Intel Xeon @ 2.60GHz, 16 vCPUs. PHP 8.4.27 NTS without the turbo extension.
Tests
make testspasses without the extension. The only failures were twoDirectoryWalkerTestcases that failed only under parallel load; that test passes when run alone and is unrelated to this change.make testspasses withphpstan_turbo.soloaded.turbo-ext/tests/smoke.phpprints ALL OK, andturbo-ext/tests/signature-parity.phppasses.turbo-ext/bin/side-by-side.phppairsInitializerExprTypeResolver. Some generated headers are reported stale; that comes from the PHP 8.4 environment and also happens without this change.src/Reflection/InitializerExprTypeResolver.phpis clean, and self-analysis of that file withbuild/phpstan.neonfinds no errors.tests/PHPStan/Analyser/nsrt/class-constant-native-type.phpfrom 9b24ee5 still passes.