Skip to content

Instantly share code, notes, and snippets.

@colinmollenhour
Created February 14, 2010 18:46
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save colinmollenhour/304180 to your computer and use it in GitHub Desktop.
Save colinmollenhour/304180 to your computer and use it in GitHub Desktop.
call_user_func_array performance comparison
<?php
$iterations = 100000;
echo "Iterations: $iterations\n";
class Test {
public function nothing0(){}
public function nothing1($arg1){}
public function nothing2($arg1,$arg2){}
public function nothing3($arg1,$arg2,$arg3){}
public function nothing4($arg1,$arg2,$arg3,$arg4){}
public function __call($name,$args){
if($name == 'iusecall')
return $this->nothing2($args[0],$args[1]);
}
}
class TestCUFA {
public function nothing2($arg1,$arg2){}
public function __call($name,$args){
return call_user_func_array(array($this,'nothing2'),$args);
}
}
class TestSwitch {
public function nothing2($arg1,$arg2){}
public function __call($name,$args){
switch($name){
case 'func1': return $this->nothing2($args[0],$args[1]); break;
case 'func2': return $this->nothing2($args[0],$args[1]); break;
case 'func3': return $this->nothing2($args[0],$args[1]); break;
case 'func4': return $this->nothing2($args[0],$args[1]); break;
case 'func5': return $this->nothing2($args[0],$args[1]); break;
case 'func6': return $this->nothing2($args[0],$args[1]); break;
case 'func7': return $this->nothing2($args[0],$args[1]); break;
case 'func8': return $this->nothing2($args[0],$args[1]); break;
case 'func9': return $this->nothing2($args[0],$args[1]); break;
case 'func10': return $this->nothing2($args[0],$args[1]); break;
case 'func11': return $this->nothing2($args[0],$args[1]); break;
case 'func12': return $this->nothing2($args[0],$args[1]); break;
case 'func13': return $this->nothing2($args[0],$args[1]); break;
case 'func14': return $this->nothing2($args[0],$args[1]); break;
case 'func15': return $this->nothing2($args[0],$args[1]); break;
case 'func16': return $this->nothing2($args[0],$args[1]); break;
}
}
}
class TestSwitchExtract {
public function nothing2($arg1,$arg2){}
public function func1($arg1,$arg2){ return $this->_call('func1',array('arg1' => $arg1, 'arg2' => $arg2)); }
public function func2($arg1,$arg2){ return $this->_call('func2',array('arg1' => $arg1, 'arg2' => $arg2)); }
public function func3($arg1,$arg2){ return $this->_call('func3',array('arg1' => $arg1, 'arg2' => $arg2)); }
public function func4($arg1,$arg2){ return $this->_call('func4',array('arg1' => $arg1, 'arg2' => $arg2)); }
public function func5($arg1,$arg2){ return $this->_call('func5',array('arg1' => $arg1, 'arg2' => $arg2)); }
public function func6($arg1,$arg2){ return $this->_call('func6',array('arg1' => $arg1, 'arg2' => $arg2)); }
public function func7($arg1,$arg2){ return $this->_call('func7',array('arg1' => $arg1, 'arg2' => $arg2)); }
public function func8($arg1,$arg2){ return $this->_call('func8',array('arg1' => $arg1, 'arg2' => $arg2)); }
public function func9($arg1,$arg2){ return $this->_call('func9',array('arg1' => $arg1, 'arg2' => $arg2)); }
public function func10($arg1,$arg2){ return $this->_call('func10',array('arg1' => $arg1, 'arg2' => $arg2)); }
public function func11($arg1,$arg2){ return $this->_call('func11',array('arg1' => $arg1, 'arg2' => $arg2)); }
public function func12($arg1,$arg2){ return $this->_call('func12',array('arg1' => $arg1, 'arg2' => $arg2)); }
public function func13($arg1,$arg2){ return $this->_call('func13',array('arg1' => $arg1, 'arg2' => $arg2)); }
public function func14($arg1,$arg2){ return $this->_call('func14',array('arg1' => $arg1, 'arg2' => $arg2)); }
public function func15($arg1,$arg2){ return $this->_call('func15',array('arg1' => $arg1, 'arg2' => $arg2)); }
public function func16($arg1,$arg2){ return $this->_call('func16',array('arg1' => $arg1, 'arg2' => $arg2)); }
public function _call($name,$args){
extract($args);
switch($name){
case 'func1': return $this->nothing2($arg1,$arg2); break;
case 'func2': return $this->nothing2($arg1,$arg2); break;
case 'func3': return $this->nothing2($arg1,$arg2); break;
case 'func4': return $this->nothing2($arg1,$arg2); break;
case 'func5': return $this->nothing2($arg1,$arg2); break;
case 'func6': return $this->nothing2($arg1,$arg2); break;
case 'func7': return $this->nothing2($arg1,$arg2); break;
case 'func8': return $this->nothing2($arg1,$arg2); break;
case 'func9': return $this->nothing2($arg1,$arg2); break;
case 'func10': return $this->nothing2($arg1,$arg2); break;
case 'func11': return $this->nothing2($arg1,$arg2); break;
case 'func12': return $this->nothing2($arg1,$arg2); break;
case 'func13': return $this->nothing2($arg1,$arg2); break;
case 'func14': return $this->nothing2($arg1,$arg2); break;
case 'func15': return $this->nothing2($arg1,$arg2); break;
case 'func16': return $this->nothing2($arg1,$arg2); break;
}
}
}
$test = new Test;
$testCUFA = new TestCUFA;
$testSwitch = new TestSwitch;
$testSwitchExtract = new TestSwitchExtract;
$args0 = array();
$args1 = array('foo');
$args2 = array('foo','bar');
$args3 = array('foo','bar','baz');
$args4 = array('foo','bar','baz','yay');
for($i = 0; $i < 5; $i++){
$args = 'args'.$i;
$args = $$args;
$start = microtime(TRUE);
for($j = 0; $j < $iterations; $j++) {
call_user_func_array(array($test,'nothing'.$i),$args);
}
$stop = microtime(TRUE) - $start;
echo "call_user_func_array $i args: $stop\n";
}
$start = microtime(TRUE);
for($j = 0; $j < $iterations; $j++) {
$test->nothing0();
}
$stop = microtime(TRUE) - $start;
echo "\$test->nothing0(): $stop\n";
$start = microtime(TRUE);
for($j = 0; $j < $iterations; $j++) {
$arg1 = $args1[0];
$test->nothing1($arg1);
}
$stop = microtime(TRUE) - $start;
echo "\$test->nothing1(\$arg1): $stop\n";
$start = microtime(TRUE);
for($j = 0; $j < $iterations; $j++) {
$arg1 = $args1[0];
$arg2 = $args2[1];
$test->nothing1($arg1, $arg2);
}
$stop = microtime(TRUE) - $start;
echo "\$test->nothing2(\$arg1,\$arg2): $stop\n";
$start = microtime(TRUE);
for($j = 0; $j < $iterations; $j++) {
$name = 'blah';
switch($name){
case 'func1': break;
case 'func2': break;
case 'func3': break;
case 'func4': break;
case 'func5': break;
case 'func6': break;
case 'func7': break;
case 'func8': break;
case 'func9': break;
case 'func10': break;
case 'func11': break;
case 'func12': break;
case 'blah':
$test->nothing2($args[0], $args[1]);
break;
}
}
$stop = microtime(TRUE) - $start;
echo "\$test->nothing2(\$args[0],\$args[1]) within switch: $stop\n";
$start = microtime(TRUE);
for($j = 0; $j < $iterations; $j++) {
$test->iusecall('foo','bar');
}
$stop = microtime(TRUE) - $start;
echo "\$test->iusecall() $stop\n";
$start = microtime(TRUE);
for($j = 0; $j < $iterations; $j++) {
$testCUFA->iusecallandcufa('foo','bar');
}
$stop = microtime(TRUE) - $start;
echo "\$testCUFA->iusecallandcufa('foo','bar') $stop\n";
for($i = 1; $i < 17; $i++) {
$start = microtime(TRUE);
$func = 'func'.$i;
for($j = 0; $j < $iterations; $j++) {
$testSwitch->$func('foo','bar');
}
$stop = microtime(TRUE) - $start;
echo "\$testSwitch->$func('foo','bar') $stop\n";
}
for($i = 1; $i < 17; $i++) {
$start = microtime(TRUE);
$func = 'func'.$i;
for($j = 0; $j < $iterations; $j++) {
$testSwitchExtract->$func('foo','bar');
}
$stop = microtime(TRUE) - $start;
echo "\$testSwitchExtract->$func('foo','bar') $stop\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment