Skip to content

Commit f1849fb

Browse files
authored
[perf] Memoize StaticPHPUnitEnvironment::isPHPUnitRun (#8732)
1 parent 4652e70 commit f1849fb

2 files changed

Lines changed: 57 additions & 1 deletion

File tree

‎bench/phpunit_env_bench.php‎

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* Benchmark for StaticPHPUnitEnvironment::isPHPUnitRun().
7+
*
8+
* The method answers a per-process constant (PHPUNIT_COMPOSER_INSTALL is defined once at phpunit
9+
* bootstrap, never after), yet it is called hundreds of thousands of times per Rector run -
10+
* Skipper::resolveSkippedClasses() alone calls it once per skip resolution. Without memoization
11+
* each call pays a defined() lookup.
12+
*
13+
* Run on both branches to compare:
14+
* php bench/phpunit_env_bench.php
15+
*
16+
* Reports CPU time (user+sys) and wall time; CPU is the reliable metric, wall is noisy
17+
* under concurrent load.
18+
*/
19+
20+
use Rector\Testing\PHPUnit\StaticPHPUnitEnvironment;
21+
22+
require __DIR__ . '/../vendor/autoload.php';
23+
24+
const CALLS = 255_000; // calls per run, matching a real run's isPHPUnitRun() volume
25+
const REPEAT = 200; // outer repeats
26+
27+
$cpuSeconds = static function (): float {
28+
$usage = getrusage();
29+
return $usage['ru_utime.tv_sec'] + $usage['ru_utime.tv_usec'] / 1_000_000
30+
+ $usage['ru_stime.tv_sec'] + $usage['ru_stime.tv_usec'] / 1_000_000;
31+
};
32+
33+
$run = static function (): void {
34+
for ($i = 0; $i < CALLS; ++$i) {
35+
StaticPHPUnitEnvironment::isPHPUnitRun();
36+
}
37+
};
38+
39+
// warm up once, excluded from timing
40+
$run();
41+
42+
$cpuStart = $cpuSeconds();
43+
$wallStart = hrtime(true);
44+
45+
for ($repeat = 0; $repeat < REPEAT; ++$repeat) {
46+
$run();
47+
}
48+
49+
printf('StaticPHPUnitEnvironment::isPHPUnitRun benchmark%s', PHP_EOL);
50+
printf(' calls=%d repeat=%d%s', CALLS, REPEAT, PHP_EOL);
51+
printf('%s', PHP_EOL);
52+
printf(' isPHPUnitRun cpu=%.4fs wall=%.4fs%s', $cpuSeconds() - $cpuStart, (hrtime(true) - $wallStart) / 1_000_000_000, PHP_EOL);

‎src/Testing/PHPUnit/StaticPHPUnitEnvironment.php‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@
66

77
final class StaticPHPUnitEnvironment
88
{
9+
// the constant is defined once at phpunit bootstrap and never changes within a process,
10+
// so the lookup is memoized - isPHPUnitRun() is called hundreds of thousands of times per run
11+
private static ?bool $isPHPUnitRun = null;
12+
913
/**
1014
* Never ever used static methods if possible, this is just handy for tests + src to prevent duplication.
1115
*/
1216
public static function isPHPUnitRun(): bool
1317
{
14-
return defined('PHPUNIT_COMPOSER_INSTALL');
18+
return self::$isPHPUnitRun ??= defined('PHPUNIT_COMPOSER_INSTALL');
1519
}
1620
}

0 commit comments

Comments
 (0)