1

I was wondering about what the best practices are when it comes to call a class method using the above functions to fill up a method call dynamically using an array!

What advantages and disadvantages do I have? I mean, it seems the RefelectionMethod + invokeArgs option is up to 40% faster than the call_user_funcion in certain conditions… but do I miss something?

thanks.

As requested i will add a little benchmark of my scenario where i needed refereces to be passed... i know its a very specific case and that this is not stricly related to the question above!

class foo { public function bar(&$a, &$b, &$c) { /* */ } }
$t1 = microtime(true);
$arr = array(1,2,3);
$foo = new foo;
$rfl = new ReflectionMethod('foo', 'bar');
for ($i=0; $i < 10000; ++$i)
{   
    $rfl->invokeArgs($foo, $arr);   
}

$t2 = microtime(true);
echo sprintf("\nElapsed reflectionmethod  : %f", $t2 - $t1);
$t1 = microtime(true);
$arr = array(1,2,3);
$foo = new foo;

for ($i=0; $i < 10000; ++$i)
{
    foreach( $arr as $k => $v ) $ref[$k] = &$arr[$k];       
    call_user_func_array( array($foo, 'bar'), $arr);
}

$t2 = microtime(true);
echo sprintf("\nElapsed calluserfuncarray : %f", $t2 - $t1);

the result

Elapsed reflectionmethod  : 0.025099
Elapsed calluserfuncarray : 0.051189

I really would just like to know when its better to use one versus the other, and why! its not strictly related to speed though!

6
  • "I mean, it seems the RefelectionMethod + invokeArgs option is up to 40% faster than the call_user_funcion" -- could you please add a test case for that? Commented Nov 25, 2012 at 22:05
  • @zerkms I've done just a very few and specific tests on this but i will eventually add them to the end of the question :) Commented Nov 25, 2012 at 22:10
  • You know, you could just adjust the line spacing in your IDE... Commented Nov 25, 2012 at 22:52
  • @phant0m its not the ide, its me. i like it more when its explosed like that! thanks for fixing formatting btw it saves some space :) Commented Nov 25, 2012 at 22:58
  • Yes, but some IDEs can make lines taller so you get the effect of having multiple lines without actually having any physically (or virtually, I should say) ;) Commented Nov 25, 2012 at 23:01

1 Answer 1

5

Not sure where you got your test results but RefelectionMethod + invokeArgs option is up to 40% faster than the call_user_funcion seems far fetched it can only be possible with single instance multiple invoke

Simple Benchmark

set_time_limit(0);
echo "<pre>";
class Foo {

    public function bar($arg1, $arg2) {
    }
}

$globalRefection = new ReflectionMethod('Foo', 'bar');
$globalFoo = new Foo();

// Using call_user_func_array
function m1($args) {
    $foo = new Foo();
    call_user_func_array(array($foo,"bar"), $args);
}

// Using ReflectionMethod:invoke
function m2($args) {
    $foo = new ReflectionMethod('Foo', 'bar');
    $foo->invoke(new Foo(), $args[0], $args[1]);
}

// Using ReflectionMethod:invokeArgs
function m3($args) {
    $foo = new ReflectionMethod('Foo', 'bar');
    $foo->invokeArgs(new Foo(), $args);
}

// Using Global Reflection
function m4($args) {
    global $globalRefection;
    $globalRefection->invokeArgs(new Foo(), $args);
}

// Using Global Reflection + Glbal foo
function m5($args) {
    global $globalRefection, $globalFoo;
    $globalRefection->invokeArgs($globalFoo, $args);
}

$result = array('m1' => 0,'m2' => 0,'m3' => 0,'m4' => 0,'m5' => 0);
$args = array("arg1","arg2");

for($i = 0; $i < 10000; ++ $i) {
    foreach ( array_keys($result) as $key ) {
        $alpha = microtime(true);
        $key($args);
        $result[$key] += microtime(true) - $alpha;
    }
}

echo '<pre>';
echo "Single Run\n";
print_r($result);
echo '</pre>';

Output

Single Run
Array
(
    [m1] => 0.018314599990845   <----- call_user_func_array 
    [m2] => 0.024132013320923   <----- ReflectionMethod:invoke
    [m3] => 0.021934270858765   <----- ReflectionMethod:invokeArgs
    [m4] => 0.012894868850708   <----- Global Relection
    [m5] => 0.01132345199585    <----- Global Reflection + Global Foo
)

See Live Action

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.