drvxnivoqf17568697 2017-01-04 10:56
浏览 89
已采纳

为什么在call_user_func_array()之前使用switch语句

I've been looking through the laravel source code and I stumbled across this in the callStatic magic method:

switch (count($args)) {
    case 0:
        return $instance->$method();
    case 1:
        return $instance->$method($args[0]);
    case 2:
        return $instance->$method($args[0], $args[1]);
    case 3:
        return $instance->$method($args[0], $args[1], $args[2]);
    case 4:
        return $instance->$method($args[0], $args[1], $args[2], $args[3]);
    default:
        return call_user_func_array([$instance, $method], $args);
}

Why is the switch statement used first and then call_user_func_array()?

  • 写回答

1条回答 默认 最新

  • douji1077 2017-01-04 14:53
    关注

    As Clive has mentioned in the comments; it's because of the performance concerns.

    call_user_func_array() is widely known for its performance issues. It's even slower than its sister function call_user_func() by 10-20% as some benchmarks revealed.

    Here's the result of a benchmark ran to compare the performance of straight calls vs. dynamic calls vs. calls through call_user_func* functions:

    • Dynamic function calls are slightly slower than straight calls (the former have an extra interpretive layer to determine the function to call call_user_func() is about 50% slower, and call_user_func_array() is about 100% slower than a straight function call.

    • Static and regular method calls are roughly equivalent to function calls call_user_func() on method calls is typically slower than call_user_func_array(), and the faster operation usually takes at least twice the execution time of a straight call.
      Matthew Weier O'Phinney

    Paul M. Jones, another well-known PHP developer, also ran a benchmark on the exact same subject and concluded that:

    So native calls to htmlentities() are twice as fast as doing effectively the same thing via call_user_func() with an object method, and using call_user_func_array() is 10-20% slower than using call_user_func()...

    Clearly, PHP has to do a lot more work behind the scenes to map the variables to objects and parameters when using call_user_func_array().
    Paul M. Jones

    Argument Unpacking

    One last thing; As of PHP 5.6 and with the advent of argument unpacking operator (AKA spread, splat or scatter operator), you can safely rewrite that code to:

    $instance->$method(...$args);
    

    Quoting from the Argument Unpacking PHP RFC:

    Furthermore call_user_func_array has a rather large performance impact. If a large number of calls go through it, this can make a significant difference. For this reason, projects like Laravel and Drupal often replace particularly common call_user_func_array calls with a switch statements.

    The ... argument unpacking syntax is about 3.5 to 4 times faster than call_user_func_args. This solves the performance issue. Benchmark code and results.

    Also, see:
    Argument unpacking advantages over call_user_func_array

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器