Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
<?php
// Run this as `php-cgi -T 100000 no_variance.php > /dev/null`
class A {
function foo(A $b) {}
}
class B extends A {
function foo(A $b) {}
}
<?php
class Foo {
static public $static_prop = 42;
static public int $typed_static_prop = 42;
public $prop = 42;
public int $typed_prop = 42;
}
function func1($x) {
return $x + 1;
}
function simple_func($n) {
for ($i = 0; $i < $n; $i++)
func1(42);
}
function func2(int $x) {
return $x + 1;
}
function typed_param($n) {
for ($i = 0; $i < $n; $i++)
func2(42);
}
function func3($x): int {
return $x + 1;
}
function typed_ret($n) {
for ($i = 0; $i < $n; $i++)
func3(42);
}
function func4(int $x): int {
return $x + 1;
}
function typed_func($n) {
for ($i = 0; $i < $n; $i++)
func4(42);
}
function func5($a, $b, $c, $d, $e) {
return $a + $b + $c + $d + $e;
}
function simple_func5($n) {
for ($i = 0; $i < $n; $i++)
func5(1, 2, 3, 4, 5);
}
function func6(int $a, int $b, int $c, int $d, int $e) : int {
return $a + $b + $c + $d + $e;
}
function typed_func5($n) {
for ($i = 0; $i < $n; $i++)
func5(1, 2, 3, 4, 5);
}
function simple_static_prop($n) {
for ($i = 0; $i < $n; $i++)
Foo::$static_prop = $i;
}
function typed_static_prop($n) {
for ($i = 0; $i < $n; $i++)
Foo::$typed_static_prop = $i;
}
function simple_prop($n) {
$o = new Foo;
for ($i = 0; $i < $n; $i++) {
$o->prop = $i;
}
unset($o);
}
function typed_prop($n) {
$o = new Foo;
for ($i = 0; $i < $n; $i++) {
$o->typed_prop = $i;
}
unset($o);
}
function simple_static_prop_inc($n) {
for ($i = 0; $i < $n; $i++)
Foo::$static_prop += 2;
}
function typed_static_prop_inc($n) {
for ($i = 0; $i < $n; $i++)
Foo::$typed_static_prop += 2;
}
function simple_prop_inc($n) {
$o = new Foo;
for ($i = 0; $i < $n; $i++) {
$o->prop += 2;
}
unset($o);
}
function typed_prop_inc($n) {
$o = new Foo;
for ($i = 0; $i < $n; $i++) {
$o->typed_prop += 2;
}
unset($o);
}
function simple_static_prop_ref($n) {
$ref = &Foo::$static_prop;
for ($i = 0; $i < $n; $i++)
$ref = $i;
}
function typed_static_prop_ref($n) {
$ref = &Foo::$typed_static_prop;
for ($i = 0; $i < $n; $i++)
$ref = $i;
}
function simple_static_prop_ref_inc($n) {
$ref = &Foo::$static_prop;
for ($i = 0; $i < $n; $i++)
$ref += 2;
}
function typed_static_prop_ref_inc($n) {
$ref = &Foo::$typed_static_prop;
for ($i = 0; $i < $n; $i++)
$ref += 2;
}
/*****/
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 = 50000000;
$t0 = $t = start_test();
empty_loop(N);
$t = end_test($t, 'empty_loop');
$overhead = $last_time;
simple_func(N);
$t = end_test($t, 'func($x)', $overhead);
typed_param(N);
$t = end_test($t, 'func(int $x)', $overhead);
typed_ret(N);
$t = end_test($t, 'func($x): int', $overhead);
typed_func(N);
$t = end_test($t, 'func(int $x): int', $overhead);
simple_func5(N);
$t = end_test($t, 'func($a,$b,$c,$d,$e)', $overhead);
typed_func5(N);
$t = end_test($t, 'func(int $a,$b,$c,$d,$e): int', $overhead);
simple_static_prop(N);
$t = end_test($t, 'Foo::$static_prop = ...', $overhead);
typed_static_prop(N);
$t = end_test($t, 'Foo::$static_typed_prop = ...', $overhead);
simple_prop(N);
$t = end_test($t, '$o->prop = ...', $overhead);
typed_prop(N);
$t = end_test($t, '$o->typed_prop = ...', $overhead);
simple_static_prop_inc(N);
$t = end_test($t, 'Foo::$static_prop += 2', $overhead);
typed_static_prop_inc(N);
$t = end_test($t, 'Foo::$static_typed_prop += 2', $overhead);
simple_prop_inc(N);
$t = end_test($t, '$o->prop += 2', $overhead);
typed_prop_inc(N);
$t = end_test($t, '$o->typed_prop += 2', $overhead);
simple_static_prop_ref(N);
$t = end_test($t, '$static_prop_ref = ...', $overhead);
typed_static_prop_ref(N);
$t = end_test($t, '$static_typed_prop_ref = ...', $overhead);
simple_static_prop_ref_inc(N);
$t = end_test($t, '$static_prop_ref += 2', $overhead);
typed_static_prop_ref_inc(N);
$t = end_test($t, '$static_typed_prop_ref += 2', $overhead);
<?php
class Foo {
static public $static_prop = 42;
static public int $typed_static_prop = 42;
static public int|float|string $union_static_prop = 42;
public $prop = 42;
public int $typed_prop = 42;
public int|float|string $union_prop = 42;
}
class A {
}
class B {
}
class C {
}
function func1($x) {
return $x + 1;
}
function simple_func($n) {
for ($i = 0; $i < $n; $i++)
func1(42);
}
function func2(int $x) {
return $x + 1;
}
function typed_param($n) {
for ($i = 0; $i < $n; $i++)
func2(42);
}
function func2u(int|float|string $x) {
return $x + 1;
}
function union_param($n) {
for ($i = 0; $i < $n; $i++)
func2u(42);
}
function func3($x): int {
return $x + 1;
}
function typed_ret($n) {
for ($i = 0; $i < $n; $i++)
func3(42);
}
function func3u($x): int|float|string {
return $x + 1;
}
function union_ret($n) {
for ($i = 0; $i < $n; $i++)
func3(42);
}
function func4(int $x): int {
return $x + 1;
}
function typed_func($n) {
for ($i = 0; $i < $n; $i++)
func4(42);
}
function func5($a, $b, $c, $d, $e) {
return $a + $b + $c + $d + $e;
}
function simple_func5($n) {
for ($i = 0; $i < $n; $i++)
func5(1, 2, 3, 4, 5);
}
function func6(int $a, int $b, int $c, int $d, int $e) : int {
return $a + $b + $c + $d + $e;
}
function typed_func5($n) {
for ($i = 0; $i < $n; $i++)
func5(1, 2, 3, 4, 5);
}
function simple_static_prop($n) {
for ($i = 0; $i < $n; $i++)
Foo::$static_prop = $i;
}
function typed_static_prop($n) {
for ($i = 0; $i < $n; $i++)
Foo::$typed_static_prop = $i;
}
function union_static_prop($n) {
for ($i = 0; $i < $n; $i++)
Foo::$union_static_prop = $i;
}
function simple_prop($n) {
$o = new Foo;
for ($i = 0; $i < $n; $i++) {
$o->prop = $i;
}
unset($o);
}
function typed_prop($n) {
$o = new Foo;
for ($i = 0; $i < $n; $i++) {
$o->typed_prop = $i;
}
unset($o);
}
function union_prop($n) {
$o = new Foo;
for ($i = 0; $i < $n; $i++) {
$o->union_prop = $i;
}
unset($o);
}
function simple_static_prop_inc($n) {
for ($i = 0; $i < $n; $i++)
Foo::$static_prop += 2;
}
function typed_static_prop_inc($n) {
for ($i = 0; $i < $n; $i++)
Foo::$typed_static_prop += 2;
}
function union_static_prop_inc($n) {
for ($i = 0; $i < $n; $i++)
Foo::$union_static_prop += 2;
}
function simple_prop_inc($n) {
$o = new Foo;
for ($i = 0; $i < $n; $i++) {
$o->prop += 2;
}
unset($o);
}
function typed_prop_inc($n) {
$o = new Foo;
for ($i = 0; $i < $n; $i++) {
$o->typed_prop += 2;
}
unset($o);
}
function union_prop_inc($n) {
$o = new Foo;
for ($i = 0; $i < $n; $i++) {
$o->union_prop += 2;
}
unset($o);
}
function simple_static_prop_ref($n) {
$ref = &Foo::$static_prop;
for ($i = 0; $i < $n; $i++)
$ref = $i;
}
function typed_static_prop_ref($n) {
$ref = &Foo::$typed_static_prop;
for ($i = 0; $i < $n; $i++)
$ref = $i;
}
function union_static_prop_ref($n) {
$ref = &Foo::$union_static_prop;
for ($i = 0; $i < $n; $i++)
$ref = $i;
}
function simple_static_prop_ref_inc($n) {
$ref = &Foo::$static_prop;
for ($i = 0; $i < $n; $i++)
$ref += 2;
}
function typed_static_prop_ref_inc($n) {
$ref = &Foo::$typed_static_prop;
for ($i = 0; $i < $n; $i++)
$ref += 2;
}
function union_static_prop_ref_inc($n) {
$ref = &Foo::$union_static_prop;
for ($i = 0; $i < $n; $i++)
$ref += 2;
}
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 func9(A|B|C|null $o) {
return is_object($o);
}
function union_hint1($n) {
$o = new A;
for ($i = 0; $i < $n; $i++) {
func9($o);
}
unset($o);
}
function func10(A|B|C|null $o) {
return is_object($o);
}
function union_hint2($n) {
$o = new C;
for ($i = 0; $i < $n; $i++) {
func10($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 = 50000000;
$t0 = $t = start_test();
empty_loop(N);
$t = end_test($t, 'empty_loop');
$overhead = $last_time;
simple_func(N);
$t = end_test($t, 'func($x)', $overhead);
typed_param(N);
$t = end_test($t, 'func(int $x)', $overhead);
union_param(N);
$t = end_test($t, 'func(int|float|string $x)', $overhead);
typed_ret(N);
$t = end_test($t, 'func($x): int', $overhead);
union_ret(N);
$t = end_test($t, 'func($x): int|float|string', $overhead);
typed_func(N);
$t = end_test($t, 'func(int $x): int', $overhead);
simple_func5(N);
$t = end_test($t, 'func($a,$b,$c,$d,$e)', $overhead);
typed_func5(N);
$t = end_test($t, 'func(int $a,$b,$c,$d,$e): int', $overhead);
simple_static_prop(N);
$t = end_test($t, 'Foo::$static_prop = ...', $overhead);
typed_static_prop(N);
$t = end_test($t, 'Foo::$static_typed_prop = ...', $overhead);
union_static_prop(N);
$t = end_test($t, 'Foo::$static_union_prop = ...', $overhead);
simple_prop(N);
$t = end_test($t, '$o->prop = ...', $overhead);
typed_prop(N);
$t = end_test($t, '$o->typed_prop = ...', $overhead);
union_prop(N);
$t = end_test($t, '$o->union_prop = ...', $overhead);
simple_static_prop_inc(N);
$t = end_test($t, 'Foo::$static_prop += 2', $overhead);
typed_static_prop_inc(N);
$t = end_test($t, 'Foo::$static_typed_prop += 2', $overhead);
union_static_prop_inc(N);
$t = end_test($t, 'Foo::$typed_union_prop += 2', $overhead);
simple_prop_inc(N);
$t = end_test($t, '$o->prop += 2', $overhead);
typed_prop_inc(N);
$t = end_test($t, '$o->typed_prop += 2', $overhead);
union_prop_inc(N);
$t = end_test($t, '$o->union_prop += 2', $overhead);
simple_static_prop_ref(N);
$t = end_test($t, '$static_prop_ref = ...', $overhead);
typed_static_prop_ref(N);
$t = end_test($t, '$static_typed_prop_ref = ...', $overhead);
union_static_prop_ref(N);
$t = end_test($t, '$static_union_prop_ref = ...', $overhead);
simple_static_prop_ref_inc(N);
$t = end_test($t, '$static_prop_ref += 2', $overhead);
typed_static_prop_ref_inc(N);
$t = end_test($t, '$static_typed_prop_ref += 2', $overhead);
union_static_prop_ref_inc(N);
$t = end_test($t, '$static_union_prop_ref += 2', $overhead);
no_hint(N);
$t = end_test($t, 'func($obj)', $overhead);
class_hint(N);
$t = end_test($t, 'func(?A $obj)', $overhead);
union_hint1(N);
$t = end_test($t, 'func(A|B|C|null $obj)', $overhead);
union_hint2(N);
$t = end_test($t, 'func(A|B|C|null $obj)', $overhead);
<?php
// Run this as `php-cgi -T 100000 variance.php > /dev/null`
class A {
function foo(B $b) {}
}
class B extends A {
function foo(A $b) {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.