Repository navigation
Measure benchmarks by counted instructions with CodSpeed instead of phpbench - #6974
Open
ondrejmirtes wants to merge 1 commit into
Open
ondrejmirtes wants to merge 1 commit into
ondrejmirtes wants to merge 1 commit into
Conversation
Comment on lines
+51
to
+52
| - name: "Checkout" | ||
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 |
Comment on lines
+83
to
+84
| - name: "Checkout" | ||
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 |
ondrejmirtes
force-pushed
the
codspeed-benchmarks
branch
2 times, most recently
from
November 6, 2026 19:50
663821c to
62c73e0
Compare
ondrejmirtes
force-pushed
the
codspeed-benchmarks
branch
from
November 6, 2026 22:33
62c73e0 to
8c73bd4
Compare
ondrejmirtes
force-pushed
the
codspeed-benchmarks
branch
from
November 7, 2026 07:54
8c73bd4 to
4efdd47
Compare
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
|
|
||
| - name: "Install PHP" | ||
| uses: "shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962" # 2.40.0 |
| ini-file: production | ||
| ini-values: memory_limit=-1 | ||
|
|
||
| - uses: "ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda" # v4.0.0 |
| - uses: "ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda" # v4.0.0 | ||
|
|
||
| - name: "Install CodSpeed" | ||
| run: | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
|
|
||
| - name: "Install PHP" | ||
| uses: "shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962" # 2.40.0 |
| coverage: "none" | ||
| php-version: "8.5" | ||
|
|
||
| - uses: "ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda" # v4.0.0 |
ondrejmirtes
force-pushed
the
codspeed-benchmarks
branch
2 times, most recently
from
November 7, 2026 08:24
e82f34e to
1402cbf
Compare
…hpbench Counts the executed instructions of only the benchmark file's analysis under CodSpeed's CPU simulation, so the numbers no longer depend on the runner. Compares them with tests/bench/expected.neon in a sharded Benchmarks workflow and removes phpbench. Amp-Thread-ID: https://ampcode.com/threads/T-01a1ad6c-dec2-72ff-bbe8-5b3b62746c94
ondrejmirtes
force-pushed
the
codspeed-benchmarks
branch
from
November 7, 2026 09:06
1402cbf to
11b4bbc
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.
The phpbench job measures wall-clock time on shared GitHub runners, so its numbers move with the runner rather than with the code. It currently fails on 2.3.x itself. This PR replaces it with a Benchmarks workflow that counts executed instructions under CodSpeed's CPU simulation (Valgrind with a fixed simulated cache). The counts do not depend on the runner, so a change in them comes from the code.
How a benchmark is measured
tests/bench/measure.phpboots PHPStan in-process, analysestests/bench/Warmup.phpto load and compile the common code paths, then measures only the analysis of the benchmark file. Start/stop comes from CodSpeed's instrument-hooks library, called over FFI. Boot (about 5 G instructions) is no longer part of every number.tests/bench/run.phpruns one benchmark. First it runs natively, with a 60 s timeout, to fill the caches in a tmpDir of its own and catch infinite loops early. Then it runs undercodspeed run --mode=simulationwith a 90 min timeout. It records instructions, estimated cycles (instructions + 10 × L1 misses + 100 × LL misses) and peak memory.tests/bench/phpstan.neonis the config the benchmarks are analysed with: level 8, bleedingEdge,inferPrivatePropertyTypeFromConstructor.tests/bench/datastays excluded from PHPStan's own analysis.The workflow
shard.phpsplitstests/bench/datainto 4 shards by expected instruction count (longest first). Each shard runs its benchmarks in parallel, one per CPU.compare.phpcompares everything withtests/bench/expected.neon. A metric may differ by 5 % (10 % for memory), and by at least 25 M instructions / 35 M estimated cycles, so the quickest benchmarks, which mostly run shared code, are not held to a fraction of a millisecond. I picked that floor from measuring every benchmark under 1 G at 2.3.0, 2.3.5 and 2.3.x: files under 200 M drifted by up to 11 M between releases, while the real regressions fromeea09a949/4dab5341b(40–170 M) still fail.expected.neonto be updated, because until then a later slowdown back to the old numbers would go unnoticed.tests/bench/data. The report ends with a reproducer command and the two commands that accept the new numbers from thebenchmark-measuredartifact.Numbers
expected.neonis measured at the current 2.3.x, so it includes Resolve names added by fixes only when a fix adds names #6967, Share the resolved class constant type between the native and PHPDoc passes when the constant has no PHPDoc type #6968, Index already normalized union members and overwrite markers instead of scanning them #6969, Avoid quadratic work when combining many same-shaped constant arrays #6970, Speed up the falsey isset() fold over many optional offsets #6971 and Describe array shapes once while sorting a union, memoize a union's loosely equal types #6973. Those fixes came out of bisecting this suite's numbers across releases.expected.neonin Docker (Ubuntu 24.04, ondrej PHP 8.5, CodSpeed 5.6.3), not on a GitHub runner. If this PR's first run differs anyway, I'll replace the file with that run'sbenchmark-measuredartifact.Also in this PR
bench.yml,phpbench.json,BenchCase,RegressionBench, the stored baseline, the Makefile targets and the dependency intests/composer.json.tests/PHPStan/Benchmark. All I/O stays in the scripts.tests/bench/data.