diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-08-20 01:31:03 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-08-20 02:21:38 +0900 |
| commit | ad335434e5376d29f38882d0dceb2461bfd8d5c6 (patch) | |
| tree | 629311e0c28d0a79bd6e91d91317dcc9aba64708 /scripts/linters | |
| parent | f58f79ee30e16d5ef45553982b164904a99fb73f (diff) | |
| download | php-shirabe-ad335434e5376d29f38882d0dceb2461bfd8d5c6.tar.gz php-shirabe-ad335434e5376d29f38882d0dceb2461bfd8d5c6.tar.zst php-shirabe-ad335434e5376d29f38882d0dceb2461bfd8d5c6.zip | |
perf(semver): memoize Intervals::isSubsetOf on its operand pair
isSubsetOf builds a throwaway `MultiConstraint([candidate, constraint])` and
hands it to `Intervals::get`, whose cache key is the constraint's string form.
That MultiConstraint is fresh on every call, so its memoized string form is
always cold and the whole intersection has to be stringified recursively --
profiling put `AnyConstraint: Display::fmt` at 3.6 % of self time, more than
the interval computation the cache exists to skip.
Cache the answer on the pair of operand strings instead. Both operands are
long-lived, so each one's own string memo stays warm and the throwaway
intersection is never built on a hit.
laravel/framework require --no-install (warm cache, network disabled):
instructions:u 9885142257 -> 9142874710 (-7.5 %)
cycles:u 4858265879 -> 4444135669 (-8.5 %)
wall (hyperfine, 20 runs)
1.322 s +- 0.018 s -> 1.224 s +- 0.011 s (-7.4 %)
monolog/monolog is unchanged (101.6 ms -> 100.3 ms, within noise).
composer.lock is byte-identical for both packages.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'scripts/linters')
0 files changed, 0 insertions, 0 deletions
