Skip to content

Instantly share code, notes, and snippets.

@stanlemon
Last active April 6, 2024 04:03
Show Gist options
  • Save stanlemon/9847488 to your computer and use it in GitHub Desktop.
Save stanlemon/9847488 to your computer and use it in GitHub Desktop.
Test the speed of calling a function in various ways in PHP.
<?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";
}
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
@maestroprog
Copy link

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.

@mostafaznv
Copy link

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

@goper-leo
Copy link

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

@azisyus
Copy link

azisyus commented Apr 6, 2024

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