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 MPI读取tif文件无法正常给各进程分配路径
  • ¥15 如何用MATLAB实现以下三个公式(有相互嵌套)
  • ¥30 关于#算法#的问题:运用EViews第九版本进行一系列计量经济学的时间数列数据回归分析预测问题 求各位帮我解答一下
  • ¥15 setInterval 页面闪烁,怎么解决
  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化