Skip to content

Instantly share code, notes, and snippets.

@maestroprog
Forked from stanlemon/func_speed.php
Last active May 28, 2017 15:13
Show Gist options
  • Save maestroprog/755a8a4e06a8096cf6f954fe6e8fa4d6 to your computer and use it in GitHub Desktop.
Save maestroprog/755a8a4e06a8096cf6f954fe6e8fa4d6 to your computer and use it in GitHub Desktop.
Test the speed of calling a function in various ways in PHP.
<?php
define('ITERATIONS', 10000000);
function accumulateResults(array &$results, $time, $name)
{
$arguments = substr($name, -1, 1);
$name = substr($name, 0, -2);
$results[$name][$arguments] = $time;
}
function fooBar($hello = null, $world = null, $php = null, $test = null)
{
;
}
$argument1 = 'hello';
$argument2 = 'world';
$argument3 = 'php';
$argument4 = 'test';
$results = [];
// TEST 1: native
for ($arguments = 0; $arguments <= 4; $arguments++) {
switch ($arguments) {
case 1:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
fooBar($argument1);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'native 1');
break;
case 2:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
fooBar($argument1, $argument2);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'native 2');
break;
case 3:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
fooBar($argument1, $argument2, $argument3);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'native 3');
break;
case 4:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
fooBar($argument1, $argument2, $argument3, $argument4);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'native 4');
break;
default:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
fooBar();
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'native 0');
}
}
// TEST 2: call_user_func
$times = [];
for ($arguments = 0; $arguments <= 4; $arguments++) {
switch ($arguments) {
case 1:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
call_user_func('fooBar', $argument1);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'call_user_func 1');
break;
case 2:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
call_user_func('fooBar', $argument1, $argument2);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'call_user_func 2');
break;
case 3:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
call_user_func('fooBar', $argument1, $argument2, $argument3);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'call_user_func 3');
break;
case 4:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
call_user_func('fooBar', $argument1, $argument2, $argument3, $argument4);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'call_user_func 4');
break;
default:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
call_user_func('fooBar');
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'call_user_func 0');
}
}
// TEST 3: call_user_func_array
for ($arguments = 0; $arguments <= 4; $arguments++) {
switch ($arguments) {
case 1:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
call_user_func_array('fooBar', [$argument1]);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'call_user_func_array 1');
break;
case 2:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
call_user_func_array('fooBar', [$argument1, $argument2]);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'call_user_func_array 2');
break;
case 3:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
call_user_func_array('fooBar', [$argument1, $argument2, $argument3]);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'call_user_func_array 3');
break;
case 4:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
call_user_func_array('fooBar', [$argument1, $argument2, $argument3, $argument4]);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'call_user_func_array 4');
break;
default:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
call_user_func_array('fooBar', []);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'call_user_func_array 0');
}
}
// TEST 4: variable function name
$fooBar = 'fooBar';
$times = [];
for ($arguments = 0; $arguments <= 4; $arguments++) {
switch ($arguments) {
case 1:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
$fooBar($argument1);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'variable 1');
break;
case 2:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
$fooBar($argument1, $argument2);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'variable 2');
break;
case 3:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
$fooBar($argument1, $argument2, $argument3);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'variable 3');
break;
case 4:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
$fooBar($argument1, $argument2, $argument3, $argument4);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'variable 4');
break;
default:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
$fooBar();
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'variable 0');
}
}
// TEST 5: ReflectionFunction->invoke()
$fooBar = new ReflectionFunction('fooBar');
$times = [];
for ($arguments = 0; $arguments <= 4; $arguments++) {
switch ($arguments) {
case 1:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
$fooBar->invoke($argument1);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'ReflectionFunction->invoke() 1');
break;
case 2:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
$fooBar->invoke($argument1, $argument2);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'ReflectionFunction->invoke() 2');
break;
case 3:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
$fooBar->invoke($argument1, $argument2, $argument3);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'ReflectionFunction->invoke() 3');
break;
case 4:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
$fooBar->invoke($argument1, $argument2, $argument3, $argument4);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'ReflectionFunction->invoke() 4');
break;
default:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
$fooBar->invoke();
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'ReflectionFunction->invoke() 0');
}
}
// TEST 6: ReflectionFunction->invoke()
$fooBar = new ReflectionFunction('fooBar');
$times = [];
for ($arguments = 0; $arguments <= 4; $arguments++) {
switch ($arguments) {
case 1:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
$fooBar->invokeArgs([$argument1]);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'ReflectionFunction->invokeArgs() 1');
break;
case 2:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
$fooBar->invokeArgs([$argument1, $argument2]);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'ReflectionFunction->invokeArgs() 2');
break;
case 3:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
$fooBar->invokeArgs([$argument1, $argument2, $argument3]);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'ReflectionFunction->invokeArgs() 3');
break;
case 4:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
$fooBar->invokeArgs([$argument1, $argument2, $argument3, $argument4]);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'ReflectionFunction->invokeArgs() 4');
break;
default:
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
$fooBar->invokeArgs([]);
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'ReflectionFunction->invokeArgs() 0');
}
}
// TEST 7: variable with a swtich statement
$times = [];
for ($arguments = 0; $arguments <= 4; $arguments++) {
switch ($arguments) {
case 1:
$args = [$argument1];
break;
case 2:
$args = [$argument1, $argument2];
break;
case 3:
$args = [$argument1, $argument2, $argument3];
break;
case 4:
$args = [$argument1, $argument2, $argument3, $argument4];
break;
default:
$args = [];
}
$func = 'fooBar';
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; $i++) {
switch (count($args)) {
case 0:
$func();
break;
case 1:
$func($args[0]);
break;
case 2:
$func($args[0], $args[1]);
break;
case 3:
$func($args[0], $args[1], $args[2]);
break;
case 4:
$func($args[0], $args[1], $args[2], $args[3]);
break;
}
}
$end = microtime(true);
accumulateResults($results, ($end - $start) / ITERATIONS, 'variable switch ' . $arguments);
}
uasort($results, function ($arr1, $arr2) {
return $arr1[4] < $arr2[4] ? -1 : ($arr1[4] <> $arr2[4] ? 1 : 0);
});
foreach ($results as $key => $values) {
echo str_pad($key . ':', 40, ' ', STR_PAD_RIGHT);
foreach ($values as $arguments => $time) {
printf(' %d - %.10f', $arguments, $time);
}
echo PHP_EOL;
}
native: 0.0000018658 0.0000009537 0.0000119209 0.0186583996
variable: 0.0000020720 0.0000009537 0.0000190735 0.0207200050
call_user_func: 0.0000032218 0.0000019073 0.0000691414 0.0322182178
call_user_func_array: 0.0000034505 0.0000028610 0.0002079010 0.0345051289
variable switch: 0.0000036948 0.0000028610 0.0000197887 0.0369477272
ReflectionFunction->invoke: 0.0000049277 0.0000038147 0.0000329018 0.0492768288
ReflectionFunction->invokeArgs: 0.0000052142 0.0000047684 0.0000150204 0.0521419048
variable list: 0.0000058471 0.0000047684 0.0000200272 0.0584714413
PHP 5.5.8 (cli) (built: Jan 12 2014 18:50:29)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2013 Zend Technologies
with Zend OPcache v7.0.3-dev, Copyright (c) 1999-2013, by Zend Technologies
with Xdebug v2.2.3, Copyright (c) 2002-2013, by Derick Rethans
native: 0 - 0.0000000680 1 - 0.0000000597 2 - 0.0000000583 3 - 0.0000000789 4 - 0.0000000792
call_user_func: 0 - 0.0000000652 1 - 0.0000000673 2 - 0.0000000670 3 - 0.0000000898 4 - 0.0000000946
variable: 0 - 0.0000001327 1 - 0.0000001342 2 - 0.0000001372 3 - 0.0000001631 4 - 0.0000001602
call_user_func_array: 0 - 0.0000000719 1 - 0.0000001284 2 - 0.0000001406 3 - 0.0000001990 4 - 0.0000001987
ReflectionFunction->invoke(): 0 - 0.0000001391 1 - 0.0000001552 2 - 0.0000001643 3 - 0.0000001934 4 - 0.0000001991
variable switch: 0 - 0.0000001780 1 - 0.0000002216 2 - 0.0000002672 3 - 0.0000002914 4 - 0.0000003034
ReflectionFunction->invokeArgs(): 0 - 0.0000002154 1 - 0.0000002679 2 - 0.0000002867 3 - 0.0000003333 4 - 0.0000003521
PHP 7.0.19-1~dotdeb+8.1 (cli) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
with Zend OPcache v7.0.19-1~dotdeb+8.1, Copyright (c) 1999-2017, by Zend Technologies
=============================================================================================================================
native: 0 - 0.0000002858 1 - 0.0000002816 2 - 0.0000002771 3 - 0.0000002924 4 - 0.0000002917
variable: 0 - 0.0000003283 1 - 0.0000003329 2 - 0.0000003543 3 - 0.0000003660 4 - 0.0000003535
ReflectionFunction->invoke(): 0 - 0.0000004466 1 - 0.0000004930 2 - 0.0000004942 3 - 0.0000005381 4 - 0.0000005446
variable switch: 0 - 0.0000004884 1 - 0.0000005322 2 - 0.0000006031 3 - 0.0000006394 4 - 0.0000006740
call_user_func: 0 - 0.0000006156 1 - 0.0000006869 2 - 0.0000006904 3 - 0.0000007225 4 - 0.0000007365
ReflectionFunction->invokeArgs(): 0 - 0.0000006354 1 - 0.0000007241 2 - 0.0000007677 3 - 0.0000008391 4 - 0.0000008786
call_user_func_array: 0 - 0.0000007357 1 - 0.0000008090 2 - 0.0000008542 3 - 0.0000009267 4 - 0.0000009711
PHP 5.6.30-0+deb8u1 (cli) (built: Feb 8 2017 08:50:21)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment