你好。今天我写了一个小的基准脚本来比较复制变量和创建对它们的引用的性能。我原以为,创建对大型数组的引用会比复制整个数组慢得多。这是我的基准代码:
<?php
$array = array();
for($i=0; $i<100000; $i++) {
$array[] = mt_rand();
}
function recursiveCopy($array, $count) {
if($count === 1000)
return;
$foo = $array;
recursiveCopy($array, $count+1);
}
function recursiveReference($array, $count) {
if($count === 1000)
return;
$foo = &$array;
recursiveReference($array, $count+1);
}
$time = microtime(1);
recursiveCopy($array, 0);
$copyTime = (microtime(1) - $time);
echo "Took " . $copyTime . "s \n";
$time = microtime(1);
recursiveReference($array, 0);
$referenceTime = (microtime(1) - $time);
echo "Took " . $referenceTime . "s \n";
echo "Reference / Copy: " . ($referenceTime / $copyTime);
我得到的实际结果是,recursiveReference 花费的时间大约是 recursiveCopy 的 20 倍(!)。
有人可以解释这种 PHP 行为吗?
最佳答案
PHP 很可能会实现 copy-on-write对于它的数组,这意味着当您“复制”一个数组时,PHP 不会执行物理复制内存的所有工作,直到您修改其中一个副本并且您的变量不能再引用相同的内部表示。
因此,您的基准测试存在根本性缺陷,因为您的 recursiveCopy
函数实际上并未复制对象;如果是这样,您将很快耗尽内存。
试试这个:通过分配给数组的一个元素,您可以强制 PHP 实际上 制作一个副本。您会发现内存很快就会耗尽,因为在递归函数达到其最大深度之前,所有副本都不会超出范围(并且不会被垃圾收集)。
function recursiveCopy($array, $count) {
if($count === 1000)
return;
$foo = $array;
$foo[9492] = 3; // Force PHP to copy the array
recursiveCopy($array, $count+1);
}
关于PHP 性能 : Copy vs. 引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4043426/