Last active
April 6, 2024 04:03
-
-
Save stanlemon/9847488 to your computer and use it in GitHub Desktop.
Test the speed of calling a function in various ways in 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 | |
function fooBar($hello, $world) { | |
// Nothing to see here... | |
} | |
$results = array(); | |
// TEST 1: call_user_func | |
$times = array(); | |
for ($i=0; $i<10000; $i++) { | |
$start = microtime(true); | |
call_user_func('fooBar', 'hello', 'world'); | |
$end = microtime(true); | |
$times[] = ($end - $start); | |
} | |
asort($times); | |
$results['call_user_func'] = array( | |
array_sum($times) / count($times), | |
current(array_slice($times, 0, 1)), | |
current(array_slice($times, -1, 1)), | |
array_sum($times) | |
); | |
// TEST 2: call_user_func_array | |
$times = array(); | |
for ($i=0; $i<10000; $i++) { | |
$start = microtime(true); | |
call_user_func_array('fooBar', array('hello', 'world')); | |
$end = microtime(true); | |
$times[] = ($end - $start); | |
} | |
asort($times); | |
$results['call_user_func_array'] = array( | |
array_sum($times) / count($times), | |
current(array_slice($times, 0, 1)), | |
current(array_slice($times, -1, 1)), | |
array_sum($times) | |
); | |
// TEST 3: native | |
$times = array(); | |
for ($i=0; $i<10000; $i++) { | |
$start = microtime(true); | |
fooBar('hello', 'world'); | |
$end = microtime(true); | |
$times[] = ($end - $start); | |
} | |
asort($times); | |
$results['native'] = array( | |
array_sum($times) / count($times), | |
current(array_slice($times, 0, 1)), | |
current(array_slice($times, -1, 1)), | |
array_sum($times) | |
); | |
// TEST 4: variable function name | |
$times = array(); | |
for ($i=0; $i<10000; $i++) { | |
$start = microtime(true); | |
$fooBar = 'fooBar'; | |
$fooBar('hello', 'world'); | |
$end = microtime(true); | |
$times[] = ($end - $start); | |
} | |
asort($times); | |
$results['variable'] = array( | |
array_sum($times) / count($times), | |
current(array_slice($times, 0, 1)), | |
current(array_slice($times, -1, 1)), | |
array_sum($times) | |
); | |
// TEST 5: ReflectionFunction->invoke() | |
$times = array(); | |
for ($i=0; $i<10000; $i++) { | |
$start = microtime(true); | |
$reflection = new ReflectionFunction('fooBar'); | |
$reflection->invoke('hello', 'world'); | |
$end = microtime(true); | |
$times[] = ($end - $start); | |
} | |
asort($times); | |
$results['ReflectionFunction->invoke'] = array( | |
array_sum($times) / count($times), | |
current(array_slice($times, 0, 1)), | |
current(array_slice($times, -1, 1)), | |
array_sum($times) | |
); | |
// TEST 6: ReflectionFunction->invoke() | |
$times = array(); | |
for ($i=0; $i<10000; $i++) { | |
$start = microtime(true); | |
$reflection = new ReflectionFunction('fooBar'); | |
$reflection->invokeArgs(array('hello', 'world')); | |
$end = microtime(true); | |
$times[] = ($end - $start); | |
} | |
asort($times); | |
$results['ReflectionFunction->invokeArgs'] = array( | |
array_sum($times) / count($times), | |
current(array_slice($times, 0, 1)), | |
current(array_slice($times, -1, 1)), | |
array_sum($times) | |
); | |
// TEST 7: variable with a swtich statement | |
$times = array(); | |
for ($i=0; $i<10000; $i++) { | |
$start = microtime(true); | |
$func = 'fooBar'; | |
$args = array('hello', 'world'); | |
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); | |
$times[] = ($end - $start); | |
} | |
asort($times); | |
$results['variable switch'] = array( | |
array_sum($times) / count($times), | |
current(array_slice($times, 0, 1)), | |
current(array_slice($times, -1, 1)), | |
array_sum($times) | |
); | |
// TEST 8: variable with list | |
$times = array(); | |
for ($i=0; $i<10000; $i++) { | |
$start = microtime(true); | |
$func = 'fooBar'; | |
$args = array('hello', 'world'); | |
$argc = count($args); | |
$args = $args + array_fill($argc, 10 - $argc, null); | |
list($a, $b, $c, $d, $e, $f, $g, $h, $j, $k) = $args; | |
$func($a, $b, $c, $d, $e, $f, $g, $h, $j, $k); | |
$end = microtime(true); | |
$times[] = ($end - $start); | |
} | |
asort($times); | |
$results['variable list'] = array( | |
array_sum($times) / count($times), | |
current(array_slice($times, 0, 1)), | |
current(array_slice($times, -1, 1)), | |
array_sum($times) | |
); | |
asort($results); | |
foreach ($results as $key => $value) { | |
array_walk($value, function(&$v, $k) { | |
$v = number_format($v, 10); | |
}); | |
$spaces = str_repeat(' ', 40 - strlen($key)); | |
print $key . ":" . $spaces . implode(' ', $value) . "\n"; | |
} |
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
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.0000000492 0.0000000000 0.0000011921 0.0004920959
call_user_func: 0.0000000560 0.0000000000 0.0000081062 0.0005598068
call_user_func_array: 0.0000000615 0.0000000000 0.0000011921 0.0006153584
variable: 0.0000000975 0.0000000000 0.0000081062 0.0009751320
variable switch: 0.0000001495 0.0000000000 0.0000040531 0.0014946461
ReflectionFunction->invoke: 0.0000002904 0.0000000000 0.0000150204 0.0029041767
ReflectionFunction->invokeArgs: 0.0000003242 0.0000000000 0.0000090599 0.0032415390
variable list: 0.0000004726 0.0000000000 0.0000090599 0.0047261715
PHP 7.4.9 (cli) (built: Oct 26 2020 15:17:14) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.9, Copyright (c), by Zend Technologies
native: 0.0000000455 0.0000000000 0.0000011921 0.0004551411
call_user_func: 0.0000000517 0.0000000000 0.0000011921 0.0005173683
call_user_func_array: 0.0000000677 0.0000000000 0.0000050068 0.0006768703
variable: 0.0000000914 0.0000000000 0.0000240803 0.0009143353
variable switch: 0.0000001434 0.0000000000 0.0000050068 0.0014338493
ReflectionFunction->invoke: 0.0000002131 0.0000000000 0.0000030994 0.0021307468
ReflectionFunction->invokeArgs: 0.0000002367 0.0000000000 0.0000100136 0.0023670197
variable list: 0.0000004477 0.0000000000 0.0000081062 0.0044770241
PHP 8.1.13 (cli) (built: Nov 26 2022 14:07:36) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.13, Copyright (c) Zend Technologies
with Zend OPcache v8.1.13, Copyright (c), by Zend Technologies
native: 0.0000000275 0.0000000000 0.0000011921 0.0002751350
call_user_func_array: 0.0000000299 0.0000000000 0.0000011921 0.0002989769
call_user_func: 0.0000000306 0.0000000000 0.0000011921 0.0003063679
variable: 0.0000000404 0.0000000000 0.0000011921 0.0004036427
variable switch: 0.0000000625 0.0000000000 0.0000298023 0.0006246567
ReflectionFunction->invoke: 0.0000000826 0.0000000000 0.0000021458 0.0008258820
ReflectionFunction->invokeArgs: 0.0000000932 0.0000000000 0.0000011921 0.0009319782
variable list: 0.0000001759 0.0000000000 0.0000011921 0.0017585754
PHP 8.2.17 (cli) (built: Mar 16 2024 01:08:19) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.17, Copyright (c) Zend Technologies
with Zend OPcache v8.2.17, Copyright (c), by Zend Technologies
native: 0.0000000258 0.0000000000 0.0000011921 0.0002579689
call_user_func: 0.0000000297 0.0000000000 0.0000011921 0.0002968311
call_user_func_array: 0.0000000302 0.0000000000 0.0000011921 0.0003015995
variable: 0.0000000415 0.0000000000 0.0000011921 0.0004150867
variable switch: 0.0000000607 0.0000000000 0.0000011921 0.0006067753
ReflectionFunction->invoke: 0.0000001019 0.0000000000 0.0000119209 0.0010190010
ReflectionFunction->invokeArgs: 0.0000001090 0.0000000000 0.0000021458 0.0010895729
variable list: 0.0000001727 0.0000000000 0.0000059605 0.0017273426
PHP 7.4.28 (cli) (built: Mar 29 2022 03:23:10) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have slightly improved your test.
We get interesting results when a variable number of arguments :)
On php 7:
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
Call_user_func works faster than the native call if the number of arguments is 0.