FOTD: ReflectionClass()->newInstanceArgs($args) is “slow”

  • Christian Stocker

(FOTD = Finding of the day :))

For okapi we needed to have a function which loads any class with any number of arguments. This is not so easy in PHP as it looks like and the way to do this until 5.1.3 was something like:

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:
          //etc...
     }
}

Looks ugly, but works, as long as you have as many “case” statements as you have arguments

Since 5.1.3 you can use the reflection extension to do this much nicer

function init($name,$init) {
    if (count($init) == 0) {
        return new $name();
    } else {
        $classObj = new ReflectionClass($name);
        return $classObj->newInstanceArgs($init);
    }
}

But as my gut said that ReflectionClass is not the fastest thing on earth, I made some benchmarks and indeed:

PHP 5.2 with switch    :  9.6
PHP 5.2 with reflection: 16.6
PHP 5.3 with switch    :  3.3
PHP 5.3 with reflection:  6.2

The ugly switch statement is almost twice as fast as the one with the reflection class. But even more surprising (to me) was that both are three times faster in PHP 5.3. I'm now even more looking forward to the final release of PHP 5.3.0 :)

BTW, we decided nevertheless for the reflection approach, as it is way less ugly and the performance difference will be negligible. And the unit for the figures in the benchmark is not really important, the relative comparison is what's interesting.


Tell us what you think