Repository navigation
Resolve loose comparison of two strings or two integers as identical - #6985
Open
ondrejmirtes wants to merge 2 commits into
Open
ondrejmirtes wants to merge 2 commits into
ondrejmirtes wants to merge 2 commits into
Conversation
Two strings of which one is not numeric, and two integers, cannot coerce, so their loose comparison is the identical one. resolveEqualType() now answers it through resolveIdenticalType() like the narrowing in IdenticalNarrowingHelper already does, instead of computing the values each side can loosely equal for every PHP version in the configured range. A switch over a string with many case labels or a long chain of `$string == 'constant'` conditions spent most of its time there. Amp-Thread-ID: https://ampcode.com/threads/T-01a1b250-12b7-7206-9d98-c1f38e89010e
…arison ConstantStringType::isNumericString() follows the PHP version running PHPStan, so on PHP 7.4 '1 ' counted as non-numeric and '1 ' == '1' was resolved as identical even when analysing for PHP 8, where both strings are numeric and compare equal. The same-type shortcut now also requires the constant strings to be non-numeric in each of the PHP versions the comparison is resolved for. Amp-Thread-ID: https://ampcode.com/threads/T-01a1b250-12b7-7206-9d98-c1f38e89010e
ondrejmirtes
force-pushed
the
loose-equal-same-type-fast-path
branch
from
November 6, 2026 20:51
57771fc to
b9b8ff1
Compare
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.
resolveEqualType()now resolves==between two strings (at least one of them non-numeric) or two integers throughresolveIdenticalType(). In those cases loose comparison behaves exactly like strict comparison, andIdenticalNarrowingHelperalready narrows them this way. Since 9d55d96 ("Narrow loose comparisons by the values each side can loosely equal"), the expression type of every$string == 'const'computedgetPossiblyLooselyEqualType()/getAlwaysLooselyEqualType()for both sides and for each representative PHP version. For plainstringthat is rebuilt fromtoValueSet()on every call. With the shortcut,resolveEqualType()time on the reproducers drops from ~0.4–0.5 s to ~2 ms.Narrowing precision is unchanged. The inferred types of 47
==/!=/in_array()/switchprobes on strings, numeric strings, accessory strings, constant unions and int ranges are byte-identical to 2.3.x-dev, both for PHP 8.4 and for aphpVersionrange of 7.4–8.5, with the turbo extension loaded and without it. The turbo-ext mirror inInitializerExprTypeResolver.cppgets the same shortcut.Also adds the regression bench
tests/bench/data/loose-string-comparison.php: a 1000-caseswitchand 1000if ($op == 'xN')checks.Measurements
Best of 5, wall time and peak RSS,
analyse -l 8 --debug, PHP 8.4, no turbo extension. 2.3.x-dev (8af6dd7) and this PR were compiled into PHARs with the repo's compiler, the same way as the releases.switchif ($op == 'xN')class-wp-html-processor.phpOn the trivial-file baseline, PHAR startup alone is ~1.06 s on this machine. From source with the turbo extension loaded:
switch0.80 → 0.70 s andif0.78 → 0.66 s.The
switchcase is still ~0.06 s above 2.3.0, but not because of 9d55d96. 9d55d96 with this change applied analyses it faster than its parent (0.90 s vs 0.96 s from source), so the remainder comes from other commits since 2.3.0.Verified with
make tests(with and without the turbo extension),make phpstan,make cs,turbo-ext/bin/side-by-side.php,turbo-ext/tests/smoke.phpandturbo-ext/tests/signature-parity.php.