Я нашел отчет об ошибке 2005 года, который описывает именно эту проблему: http://bugs.php.net/bug.php?id=34540
Таким образом, проблема заключается в том, что при передаче ссылочного значения в функцию, которая не принимает ссылку, PHP должен ее скопировать.
Это можно продемонстрировать с помощью этого кода теста:
<?php
function CalledFunc(&$aData)
{
// Do nothing
}
function TestFunc(&$aArray)
{
$aArray = range(0, 100000);
$fStartTime = microtime(true);
for ($iIter = 0; $iIter < 1000; $iIter++)
{
CalledFunc($aArray);
}
$fTaken = microtime(true) - $fStartTime;
print "took $fTaken seconds\n";
}
$aArray = array();
TestFunc($sData);
?>
Это выполняется быстро, но если вы измените function CalledFunc(&$aData)
на function CalledFunc($aData)
, то увидите замедление, аналогичное примеру count
.
Это довольно тревожно, так как я уже довольно давно кодирую PHP и понятия не имел об этой проблеме.
К счастью, существует простой обходной путь, который применим во многих случаях - используйте временную локальную переменную внутри цикла и скопируйте в ссылочную переменную в конце.