嘿.今天我写了一个小的基准脚本来比较复制变量的性能与创建对它们的引用.我期待,例如,创建对大型数组的引用将比复制整个数组慢得多.这是我的基准代码:
<?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大约需要20次(!),只要recursiveCopy.
有人可以解释这个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); }