Last active
January 16, 2020 14:53
-
-
Save dtakken/1539d64170921363dc8d1ed62effcd45 to your computer and use it in GitHub Desktop.
Benchmarking script for measuring type check cache performance, based on https://gist.github.com/dstogov/fb32023e8dd55e58312ae0e5029556a9#file-union_bench-php
This file contains 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
<?php | |
class A { | |
} | |
class B { | |
} | |
class C { | |
} | |
class Foo { | |
static public $static_prop = 42; | |
static public A|B|C $class_union_static_prop; | |
public A|B|C $class_union_prop; | |
} | |
class D extends C { | |
} | |
class E extends D { | |
} | |
class F extends E { | |
} | |
function func1($x) { | |
return $x + 1; | |
} | |
function simple_func($n) { | |
for ($i = 0; $i < $n; $i++) | |
func1(42); | |
} | |
function simple_static_prop($n) { | |
for ($i = 0; $i < $n; $i++) | |
Foo::$static_prop = $i; | |
} | |
function class_union_static_prop($n) { | |
$c = new C; | |
for ($i = 0; $i < $n; $i++) | |
Foo::$class_union_static_prop = $c; | |
} | |
function simple_prop($n) { | |
$o = new Foo; | |
for ($i = 0; $i < $n; $i++) { | |
$o->prop = $i; | |
} | |
unset($o); | |
} | |
function class_union_prop($n) { | |
$o = new Foo; | |
$c = new C; | |
for ($i = 0; $i < $n; $i++) { | |
$o->class_union_prop = $c; | |
} | |
unset($o); | |
} | |
function func7($o) { | |
return is_object($o); | |
} | |
function no_hint($n) { | |
$o = new A; | |
for ($i = 0; $i < $n; $i++) { | |
func7($o); | |
} | |
unset($o); | |
} | |
function func8(?A $o) { | |
return is_object($o); | |
} | |
function class_hint($n) { | |
$o = new A; | |
for ($i = 0; $i < $n; $i++) { | |
func8($o); | |
} | |
unset($o); | |
} | |
function func9a(A|B|C|null $o) { | |
return is_object($o); | |
} | |
function func9c(C|A|B|null $o) { | |
return is_object($o); | |
} | |
function func9d($o): A|B|C|null { | |
return $o; | |
} | |
function union_hint1($n) { | |
$o = new A; | |
for ($i = 0; $i < $n; $i++) { | |
func9a($o); | |
} | |
unset($o); | |
} | |
function union_hint2($n) { | |
$o = new C; | |
for ($i = 0; $i < $n; $i++) { | |
func9a($o); | |
} | |
unset($o); | |
} | |
function union_hint3($n) { | |
$o = new D; | |
for ($i = 0; $i < $n; $i++) { | |
func9a($o); | |
} | |
unset($o); | |
} | |
function union_hint4($n) { | |
$o = new E; | |
for ($i = 0; $i < $n; $i++) { | |
func9a($o); | |
} | |
unset($o); | |
} | |
function union_hint5($n) { | |
$o = null; | |
for ($i = 0; $i < $n; $i++) { | |
func9c($o); | |
} | |
unset($o); | |
} | |
function union_hint6($n) { | |
$o = new F; | |
for ($i = 0; $i < $n; $i++) { | |
func9a($o); | |
} | |
unset($o); | |
} | |
function union_hint7($n) { | |
$o = new A; | |
for ($i = 0; $i < $n; $i++) { | |
func9d($o); | |
} | |
unset($o); | |
} | |
function union_hint8($n) { | |
$o = new C; | |
for ($i = 0; $i < $n; $i++) { | |
func9d($o); | |
} | |
unset($o); | |
} | |
function union_hint9($n) { | |
$o = new D; | |
for ($i = 0; $i < $n; $i++) { | |
func9d($o); | |
} | |
unset($o); | |
} | |
function union_hint10($n) { | |
$o = new E; | |
for ($i = 0; $i < $n; $i++) { | |
func9d($o); | |
} | |
unset($o); | |
} | |
function union_hint11($n) { | |
$o = new F; | |
for ($i = 0; $i < $n; $i++) { | |
func9d($o); | |
} | |
unset($o); | |
} | |
/*****/ | |
function empty_loop($n) { | |
for ($i = 0; $i < $n; ++$i) { | |
} | |
} | |
function gethrtime() | |
{ | |
$hrtime = hrtime(); | |
return (($hrtime[0]*1000000000 + $hrtime[1]) / 1000000000); | |
} | |
function start_test() | |
{ | |
ob_start(); | |
return gethrtime(); | |
} | |
function end_test($start, $name, $overhead = null) | |
{ | |
global $total; | |
global $last_time; | |
$end = gethrtime(); | |
ob_end_clean(); | |
$last_time = $end-$start; | |
$total += $last_time; | |
$num = number_format($last_time,3); | |
$pad = str_repeat(" ", 40-strlen($name)-strlen($num)); | |
if (is_null($overhead)) { | |
echo $name.$pad.$num."\n"; | |
} else { | |
$num2 = number_format($last_time - $overhead,3); | |
echo $name.$pad.$num." ".$num2."\n"; | |
} | |
ob_start(); | |
return gethrtime(); | |
} | |
function total() | |
{ | |
global $total; | |
$pad = str_repeat("-", 40); | |
echo $pad."\n"; | |
$num = number_format($total,3); | |
$pad = str_repeat(" ", 40-strlen("Total")-strlen($num)); | |
echo "Total".$pad.$num."\n"; | |
} | |
const N = 50_000_000; | |
$t0 = $t = start_test(); | |
empty_loop(N); | |
$t = end_test($t, 'empty_loop'); | |
$overhead = $last_time; | |
simple_static_prop(N); | |
$t = end_test($t, 'Foo::$static_prop = ...', $overhead); | |
class_union_static_prop(N); | |
$t = end_test($t, 'Foo::$class_union_static_prop = ...', $overhead); | |
simple_prop(N); | |
$t = end_test($t, '$o->prop = ...', $overhead); | |
class_union_prop(N); | |
$t = end_test($t, '$o->class_union_prop = ...', $overhead); | |
simple_func(N); | |
$t = end_test($t, 'func($x)', $overhead); | |
no_hint(N); | |
$t = end_test($t, 'func($obj)', $overhead); | |
union_hint5(N); | |
$t = end_test($t, 'func(A|B|C|null $obj) (null)', $overhead); | |
union_hint1(N); | |
$t = end_test($t, 'func(A|B|C|null $obj) (A)', $overhead); | |
union_hint2(N); | |
$t = end_test($t, 'func(A|B|C|null $obj) (C)', $overhead); | |
union_hint3(N); | |
$t = end_test($t, 'func(A|B|C|null $obj) (D)', $overhead); | |
union_hint4(N); | |
$t = end_test($t, 'func(A|B|C|null $obj) (E)', $overhead); | |
union_hint6(N); | |
$t = end_test($t, 'func(A|B|C|null $obj) (F)', $overhead); | |
union_hint7(N); | |
$t = end_test($t, 'func($obj): A|B|C|null (A)', $overhead); | |
union_hint8(N); | |
$t = end_test($t, 'func($obj): A|B|C|null (C)', $overhead); | |
union_hint9(N); | |
$t = end_test($t, 'func($obj): A|B|C|null (D)', $overhead); | |
union_hint10(N); | |
$t = end_test($t, 'func($obj): A|B|C|null (E)', $overhead); | |
union_hint11(N); | |
$t = end_test($t, 'func($obj): A|B|C|null (F)', $overhead); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment