PHP是否优化数组类型的函数参数,而不是在未修改时通过引用显式传递


Does PHP optimize function arguments of array type, not explicitly passed by reference, when they are not modified?

PHP引擎会优化第二个示例以通过引用传递$arr吗?

function test1(array &$arr)
{
    $arr[] = 123;
    echo $arr[0];
}
function test2(array $arr)
{
    echo $arr[0];
}

PHP使用一种称为写时复制的机制来避免在不必要的情况下过度复制变量。因此,即使在test2()示例中,$array也根本不会被复制。如果您在函数中修改了$array,PHP就会复制该变量以允许修改。这个机制的详细解释可以在"PHP内部书籍"的"内存管理"一章中找到。以下引文来自"引用计数和写入时复制"部分:

如果你仔细考虑一下以上内容,你就会得出结论PHP一定做了大量的复制。每次你经过某个函数的值需要复制。这可能不是对于整数或双精度来说尤其有问题,但想象一下将一个包含1000万个元素的数组传递给一个函数。正在复制每次通话中的数百万个元素都会慢得令人望而却步。

为了避免这种情况,PHP采用了写时复制的模式:由多个变量/函数等共享,只要它是从读取而非修改。如果持有者中的一个想要修改它,在应用任何更改之前,需要复制zval。

以下两篇文章(均由PHP核心开发人员撰写)提供了对该主题的更多见解:

  • Johannes Schlüter:不要使用PHP引用
  • Sara Golemon:你被欺骗了

第一个甚至解释了为什么仅仅出于性能原因使用引用通常是个坏主意:

人们使用参考的另一个原因是,他们认为代码更快。但这是错误的。更糟糕的是:参考文献大多让代码变慢!

是的,引用经常会使代码变慢-对不起,我只是不得不重复这个以使其清楚。

第二个例子说明了为什么在PHP5+中对象并没有真正通过引用传递。