一尘不染

为什么在参考值上调用函数(例如strlen,count等)这么慢?

php

我刚刚在PHP中发现了一些非常奇怪的东西。

如果我通过引用将变量传递给函数,然后在其上调用函数,则它的运行速度会 非常 慢。

如果循环遍历内部函数调用并且变量较大,则与通过值传递变量相比,速度可能慢许多个数量级。

例:

<?php
function TestCount(&$aArray)
{
    $aArray = range(0, 100000);
    $fStartTime = microtime(true);

    for ($iIter = 0; $iIter < 1000; $iIter++)
    {
        $iCount = count($aArray);
    }

    $fTaken = microtime(true) - $fStartTime;

    print "took $fTaken seconds\n";
}

$aArray = array();
TestCount($aArray);
?>

在我的机器上(在PHP 5.3上)运行始终需要大约20秒。

但是,如果我将函数更改为按值传递(即function TestCount($aArray)而不是function TestCount(&$aArray)),那么它将运行约2毫秒- 实际上快10,000倍

对于其他内置函数(例如strlen)和用户定义的函数也是如此。

这是怎么回事?


阅读 238

收藏
2020-05-29

共1个答案

一尘不染

我从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了很长时间,而且我对这个问题一无所知。

幸运的是,有一个简单的解决方法适用于许多情况-在循环中使用临时局部变量,最后复制到参考变量。

2020-05-29