Skip to content

Instantly share code, notes, and snippets.

@greut
Created September 19, 2008 12:08
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 greut/11582 to your computer and use it in GitHub Desktop.
Save greut/11582 to your computer and use it in GitHub Desktop.
<?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";
@rafi
Copy link

rafi commented Dec 14, 2013

  • What's different in init2() (line 99) and init5() (line 119) ?
  • Running the test measurements, for "init5" you're still "init4" with A (line 148) and B (155) ?

So this means the measurement for "init2" which uses reflection with A isn't that bad.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment