Skip to content

Instantly share code, notes, and snippets.

@staabm
Created August 16, 2026 06:49
Show Gist options
  • Select an option

  • Save staabm/7154c8b38df6c740f5f9ab58052b0fec to your computer and use it in GitHub Desktop.

Select an option

Save staabm/7154c8b38df6c740f5f9ab58052b0fec to your computer and use it in GitHub Desktop.
instanceof_fast_path_repro.php
@ -0,0 +1,133 @@
<?php
declare(strict_types=1);
/**
* Reproducer for commit 559d1f63893f5262ad3da2cbb748b77d56a8af2f:
* "Defer SAVE_OPLINE() on the INSTANCEOF fast path"
*
* Run this on a build before and after that commit.
* The instance-of cases should get faster after the change.
*/
if (PHP_SAPI !== 'cli') {
fwrite(STDERR, "Run from CLI.\n");
exit(1);
}
class HitTarget
{
}
interface HitMarker
{
}
final class HitChild extends HitTarget implements HitMarker
{
}
function run_case(string $label, int $rounds, callable $fn): array
{
$times = [];
$sink = 0;
$sink ^= $fn();
for ($r = 0; $r < $rounds; $r++) {
$start = hrtime(true);
$sink ^= $fn();
$times[] = (hrtime(true) - $start) / 1e9;
}
sort($times);
return [
'label' => $label,
'best' => $times[0],
'avg' => array_sum($times) / count($times),
'sink' => $sink,
];
}
$iterations = isset($argv[1]) ? max(1, (int) $argv[1]) : 30_000_000;
$rounds = isset($argv[2]) ? max(1, (int) $argv[2]) : 7;
gc_disable();
$className = HitTarget::class;
$markerName = HitMarker::class;
$hitTarget = new HitTarget();
$hitChild = new HitChild();
$cases = [
run_case('baseline', $rounds, static function () use ($iterations): int {
$sum = 0;
for ($i = 0; $i < $iterations; $i++) {
if (($i & 1) === 0) {
$sum++;
}
}
return $sum;
}),
run_case('class-hit', $rounds, static function () use ($iterations, $hitTarget, $className): int {
$sum = 0;
for ($i = 0; $i < $iterations; $i++) {
if ($hitTarget instanceof $className) {
$sum++;
}
}
return $sum;
}),
run_case('interface-hit', $rounds, static function () use ($iterations, $hitChild, $markerName): int {
$sum = 0;
for ($i = 0; $i < $iterations; $i++) {
if ($hitChild instanceof $markerName) {
$sum++;
}
}
return $sum;
}),
];
$byLabel = [];
foreach ($cases as $row) {
$byLabel[$row['label']] = $row;
}
printf(
"PHP %s\niterations=%d rounds=%d\n\n",
PHP_VERSION,
$iterations,
$rounds
);
echo str_pad('case', 18) . str_pad('best(s)', 12) . str_pad('avg(s)', 12) . "sink\n";
echo str_repeat('-', 52) . "\n";
foreach ($cases as $row) {
printf(
"%-18s%-12.6f%-12.6f%d\n",
$row['label'],
$row['best'],
$row['avg'],
$row['sink']
);
}
echo "\ninstanceof / baseline ratios (best time, lower is better):\n";
printf(
"%-18s %.4fx\n",
'class-hit',
$byLabel['class-hit']['best'] / $byLabel['baseline']['best']
);
printf(
"%-18s %.4fx\n",
'interface-hit',
$byLabel['interface-hit']['best'] / $byLabel['baseline']['best']
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment