为什么在引用的值上调用函数(例如strlen,count等)这么慢? [英] Why is calling a function (such as strlen, count etc) on a referenced value so slow?

查看:97
本文介绍了为什么在引用的值上调用函数(例如strlen,count等)这么慢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've just found something very strange in PHP.

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

If I pass in a variable to a function by reference, and then call a function on it, it's incredibly slow.

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

If you loop over the inner function call and the variable is large it can be many orders of magnitude slower than if the variable is passed by value.

示例:

<?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秒钟才能运行.

This consistently takes about 20 seconds to run on my machine (on PHP 5.3).

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

But if I change the function to pass by value (ie function TestCount($aArray) instead of function TestCount(&$aArray)), then it runs in about 2ms - literally 10,000 times faster!

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

The same is true for other built-in functions such as strlen, and for user-defined functions.

这是怎么回事?

推荐答案

我从2005年开始发现了一个错误报告,其中准确描述了此问题:

I found a bug report from 2005 that describes exactly this issue: http://bugs.php.net/bug.php?id=34540

因此问题似乎在于,当将引用的值传递给不接受引用的函数时,PHP需要复制它.

So the problem seems to be that when passing a referenced value to a function that doesn't accept a reference, PHP needs to copy it.

这可以通过以下测试代码来演示:

This can be demonstrated with this test code:

<?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示例类似的减速情况.

This runs quickly, but if you change function CalledFunc(&$aData) to function CalledFunc($aData) you'll see a similar slow-down to the count example.

这让我很担心,因为我已经编码PHP了很长时间,而且我对此问题一无所知.

This is rather worrying, since I've been coding PHP for quite a while and I had no idea about this issue.

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

Fortunately there's a simple workaround that is applicable in many cases - use a temporary local variable inside the loop, and copy to the reference variable at the end.

这篇关于为什么在引用的值上调用函数(例如strlen,count等)这么慢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆