在PHP(> = 5.0),通过引用更快?
在PHP中,函数参数可以通过在函数声明中的参数前加一个&符号来传递,如下所示:
function foo(&$bar) { // ... }
现在,我意识到这不是为了提高性能而devise的,而是允许函数改变通常超出范围的variables。
相反,PHP似乎使用Copy On Write来避免复制对象(也可能是数组),直到它们被更改。 所以,对于不改变参数的函数,效果应该和通过引用传递它们一样。
但是,我想知道Copy On Write逻辑是否可能在通过引用时被短路,是否会对性能产生影响。
ETA:可以肯定的是,我认为这不是更快,我清楚这不是什么参考。 所以我觉得我自己的猜测是相当不错的,我只是在寻找一个真正知道底线下发生的事情的人的答案。 在PHP开发的五年中,我一直发现很难从阅读源代码中获取关于PHP内部的高质量信息。
Zend引擎使用copy-on-write,当您自己使用引用时,会引起一些额外的开销。 在撰写本文时只能find这一点 , 手册中的评论包含其他链接。
(编辑)关于对象和引用的手册页包含更多关于对象variables与引用不同的信息。
在100 000次迭代中调用一个20 kBstring的函数的testing中,结果是:
刚刚读取/使用参数的函数
pass by value: 0.12065005 seconds pass by reference: 1.52171397 seconds
写/改变参数的function
pass by value: 1.52223396 seconds pass by reference: 1.52388787 seconds
结论
-
通过值传递参数总是更快
-
如果该函数改变了传递的variables的值,出于实际的目的,与通过引用相比,通过值相同
我对此进行了一些testing,因为我不确定给出的答案。
我的结果显示,通过引用IS传递大数组或string显着更快。
这是我的结果:
Y轴(运行)是1秒钟内可以调用的函数的次数* 10
每个function/variables重复testing8次
这里是我使用的variables:
$large_array = array_fill(PHP_INT_MAX / 2, 1000, 'a'); $small_array = array('this', 'is', 'a', 'small', 'array'); $large_object = (object)$large_array; $large_string = str_repeat('a', 100000); $small_string = 'this is a small string'; $value = PHP_INT_MAX / 2;
这些是function:
function pass_by_ref(&$var) { } function pass_by_val($var) { }
我很确定,不,这不是更快。 此外,它特别在手册中说,不要尝试使用引用来提高性能。
编辑:找不到它说的地方,但它在那里!
我已经尝试了10k字节的string的值和引用,将它传递给两个相同的函数。 一个是以价值为参照,另一个是参照。 他们是共同的function – 采取参数,做简单的处理,并返回一个值。 我做了10万个电话,发现引用不是为了提高性能而devise的 – 引用的利润在4-5%左右,只有当string变得足够大时(100k或更长,提高了6-7%), 。 所以,我的结论是不要使用引用来提高性能,这个东西不是那个。
我使用PHP版本5.3.1
没有比testing代码更好的了
<?PHP $r = array(); for($i=0; $i<500;$i++){ $r[]=5; } function a($r){ $r[0]=1; } function b(&$r){ $r[0]=1; } $start = microtime(true); for($i=0;$i<9999;$i++){ //a($r); b($r); } $end = microtime(true); echo $end-$start; ?>
最后结果! 数组越大(或者呼叫次数越多)差异越大。 所以在这种情况下,通过引用调用速度更快,因为函数内部的值已更改。
否则,在“通过引用”和“按值”之间没有真正的区别,编译器足够聪明,如果没有必要,每次都不会创build新的副本。
传递对象时不需要添加&运算符。 在PHP 5+对象通过引用无论如何传递。