不确定如何确切地标题。在深入了解Laravel 4课程以了解外墙是如何工作的时候,我偶然发现了这个:
Illuminate\Support\Facades\Facades.php@__callStatic
public static function __callStatic($method, $args)
{
$instance = static::getFacadeRoot();
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(array($instance, $method), $args);
}
}
现在我可以告诉这个方法调用Facade引用的类的任何给定方法并传递参数。我可能错了,但这是我迄今为止的理解。
真正让我烦恼的部分就是转换。
为什么在默认情况下无论如何都需要0到4的情况。
如果没有参数,即使案例0有意义,为什么有案例1-4,而不仅仅是继续案例10。对此有合理的论据,还是只是过早优化的情况?
答案 0 :(得分:4)
你是对的,在不使用call_user_func_array();
声明的情况下调用switch
可以完美地工作。 但是,根据这个benchmark,它看起来非常慢:
function html($value)
{
return htmlentities($value);
}
name : diff : total : description
native : 0.614219 : 0.613295 : htmlentities($value)
literal_func : 0.745537 : 1.346594 : html($value)
variable_func : 0.826048 : 2.162376 : $func($value)
literal_method : 0.957708 : 3.127519 : $object->html($value)
variable_method : 0.840837 : 3.970290 : $object->$func($value)
call_func : 1.006599 : 4.993930 : call_user_func($func, $value)
call_object : 1.193323 : 6.215677 : call_user_func((array($object, $func), $value)
cufa_func : 1.232891 : 7.320287 : call_user_func_array($func, array($value))
cufa_object : 1.309725 : 8.769755 : call_user_func_array((array($object, $func), array($value)
所以基本上这只会在你多次使用call_user_func_array()
时成为一个问题(在Laravel就是这种情况)。这就是他们使用switch
声明的原因。
答案 1 :(得分:4)
我怀疑这是微观优化。我还怀疑大多数这些静态调用外墙需要4个或更少的参数,在这种情况下,大多数静态调用都不会跳转到默认情况。
我能够在call_user_func_array
上的手册条目中找到这个用户提交的引用来自' noone at example dot com':
对于那些必须考虑性能的人:以这种方式调用函数需要的时间大约是通过直接语句的3倍,所以只要可以避免使用这种方法,这是一个明智的想法如此。
执行非常简单基准测试似乎也证实了这一点的有效性。在结果中,1是直接调用实例上的方法,2是在实例上调用变量方法名称,3是使用call_user_func_array
,输出时间以秒为单位。每种方法的迭代次数为1,000,000。
$ php test.php
(1) total: 0.51281404495239
(2) total: 0.51285219192505
(3) total: 1.1298811435699
$ php test.php
(1) total: 0.49811697006226
(2) total: 0.5209321975708
(3) total: 1.1204349994659
$ php test.php
(1) total: 0.48825788497925
(2) total: 0.51465392112732
(3) total: 1.156769990921
上面的结果表明,除非静态方法的参数超过4个,否则避免call_user_func_array
可以加快对静态外观方法的调用,除非静态方法的参数超过4个。
至于为什么选择4个参数的截止数,只有泰勒知道。自从Laravel 4.0 first commit以来,这种方法(大部分)都没有改变,我怀疑它有些武断。
答案 2 :(得分:3)
因为$instance->$method()
方式比call_user_func_array
更快。
鉴于这段代码可以在一个周期内多次调用,因此尽可能优化它是有意义的。