Created
September 19, 2008 12:08
-
-
Save greut/11582 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 | |
// See: http://blog.liip.ch/archive/2008/09/18/fotd-reflectionclass-newinstanceargs-args-is-slow.html | |
/* Results on my box: | |
$ php -v | |
PHP 5.2.6-pl7-gentoo (cli) (built: Sep 22 2008 08:13:50) | |
Copyright (c) 1997-2008 The PHP Group | |
Zend Engine v2.2.0, Copyright (c) 1998-2008 Zend Technologies | |
$ php test.php | |
A | |
init 0.2247450352 | |
init2 0.2754812241 | |
init3 not applicable. | |
init4 0.9950580597 | |
init5 0.9901609421 | |
B | |
init 0.5811409950 | |
init2 0.6747829914 | |
init3 0.4714331627 | |
init4 1.4021868706 | |
init5 1.4017899036 | |
*/ | |
class Base { | |
function __toString() { | |
return implode(":", array($this->a, | |
$this->b, | |
$this->c, | |
$this->d, | |
$this->e, | |
$this->f)); | |
} | |
} | |
class A extends Base { | |
function __construct($a=null, $b=null, $c=null, $d=null, $e=null, $f=null) { | |
$this->a = $a; | |
$this->b = $b; | |
$this->c = $c; | |
$this->d = $d; | |
$this->e = $e; | |
$this->f = $f; | |
} | |
} | |
class B extends Base { | |
function __construct($args=null) { | |
$argnames = array( | |
"a"=>null, | |
"b"=>null, | |
"c"=>null, | |
"d"=>null, | |
"e"=>null, | |
"f"=>null); | |
$args = is_array($args) && func_num_args() == 1 ? | |
$args : | |
func_get_args(); | |
$i=0; | |
foreach($argnames as $arg => $defaultvalue) { | |
${$arg} = isset($args[$i]) ? | |
$args[$i] : | |
$defaultvalue; | |
$i++; | |
} | |
$this->a = $a; | |
$this->b = $b; | |
$this->c = $c; | |
$this->d = $d; | |
$this->e = $e; | |
$this->f = $f; | |
} | |
} | |
function init($name,$init) { | |
switch(count($init)) { | |
case 0: | |
return new $name(); | |
case 1: | |
return new $name($init[0]); | |
case 2: | |
return new $name($init[0],$init[1]); | |
case 3: | |
return new $name($init[0],$init[1],$init[2]); | |
case 4: | |
return new $name($init[0],$init[1],$init[2],$init[3]); | |
case 5: | |
return new $name($init[0],$init[1],$init[2],$init[3],$init[4]); | |
case 6: | |
return new $name($init[0],$init[1],$init[2],$init[3],$init[4],$init[5]); | |
} | |
} | |
function init2($name,$init) { | |
if (count($init) == 0) { | |
return new $name(); | |
} else { | |
$classObj = new ReflectionClass($name); | |
return $classObj->newInstanceArgs($init); | |
} | |
} | |
function init3($name, $init) { | |
return new $name($init); | |
} | |
// from: Robin Orheden | |
function init4($name, $init) { | |
$args = "\$init[" . implode("], \$init[", array_keys($init)) . "]"; | |
return class_exists($name) ? eval("return new {$name}({$args});") : false; | |
} | |
// using reflection | |
function init5($name,$init) { | |
if (count($init) == 0) { | |
return new $name(); | |
} else { | |
$classObj = new ReflectionClass($name); | |
return $classObj->newInstanceArgs($init); | |
} | |
} | |
function measure($num, $fn, $class, $args) { | |
$now = time()+microtime(); | |
for($i=0; $i<$num; $i++) { | |
$fn($class, $args); | |
} | |
return time()+microtime() - $now; | |
} | |
$args = array("a", "b", "c", "d", "e", "f"); | |
$num = 32000; | |
$view = "%.10f"; | |
new A(); | |
new B(); | |
echo "A\n"; | |
echo "init\t", sprintf($view, measure($num, "init", "A", $args)), "\n"; | |
echo "init2\t", sprintf($view, measure($num, "init2", "A", $args)), "\n"; | |
echo "init3\tnot applicable.\n"; | |
echo "init4\t", sprintf($view, measure($num, "init4", "A", $args)), "\n"; | |
echo "init5\t", sprintf($view, measure($num, "init4", "A", $args)), "\n"; | |
echo "\n"; | |
echo "B\n"; | |
echo "init\t", sprintf($view, measure($num, "init", "B", $args)), "\n"; | |
echo "init2\t", sprintf($view, measure($num, "init2", "B", $args)), "\n"; | |
echo "init3\t", sprintf($view, measure($num, "init3", "B", $args)), "\n"; | |
echo "init4\t", sprintf($view, measure($num, "init4", "B", $args)), "\n"; | |
echo "init5\t", sprintf($view, measure($num, "init4", "B", $args)), "\n"; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
init2()
(line 99) andinit5()
(line 119) ?A
(line 148) andB
(155) ?So this means the measurement for "init2" which uses reflection with
A
isn't that bad.