1

我想知道使用上述函数调用类方法以使用数组动态填充方法调用时的最佳实践是什么!

我有什么优点和缺点?我的意思是,在某些情况下,RefelectionMethod + invokeArgs 选项似乎比 call_user_funcion 快 40%……但我错过了什么吗?

谢谢。

根据要求,我将在我需要通过裁判的情况下添加一个小基准......我知道这是一个非常具体的案例,这与上述问题没有严格的关系!

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);

结果

Elapsed reflectionmethod  : 0.025099
Elapsed calluserfuncarray : 0.051189

我真的很想知道什么时候使用一个比另一个更好,为什么!虽然它与速度没有严格的关系!

4

1 回答 1

5

不知道你从哪里得到你的测试结果,但RefelectionMethod + invokeArgs option is up to 40% faster than the call_user_funcion似乎牵强附会它只能通过单实例多次调用才有可能

简单基准

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>';

输出

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
)

看真人秀

于 2012-11-25T22:32:40.617 回答