【发布时间】:2010-09-11 15:53:35
【问题描述】:
PHP 中的函数调用很昂贵。这是一个测试它的小基准:
<?php
const RUNS = 1000000;
// create test string
$string = str_repeat('a', 1000);
$maxChars = 500;
// with function call
$start = microtime(true);
for ($i = 0; $i < RUNS; ++$i) {
strlen($string) <= $maxChars;
}
echo 'with function call: ', microtime(true) - $start, "\n";
// without function call
$start = microtime(true);
for ($i = 0; $i < RUNS; ++$i) {
!isset($string[$maxChars]);
}
echo 'without function call: ', microtime(true) - $start;
这首先使用函数 (strlen) 测试功能相同的代码,然后不使用函数(isset 不是函数)。
我得到以下输出:
with function call: 4.5108239650726
without function call: 0.84017300605774
如您所见,使用函数调用的实现比不调用任何函数的实现慢五 (5.38) 倍以上。
我想知道为什么函数调用如此昂贵。主要瓶颈是什么?是在哈希表中查找吗?还是什么这么慢?
我重新审视了这个问题,并决定再次运行基准测试,完全禁用 XDebug(不仅仅是禁用分析)。这表明,我的测试相当复杂,这一次,我得到了 10000000 次运行:
with function call: 3.152988910675
without function call: 1.4107749462128
这里的函数调用只有大约两倍 (2.23) 的速度,因此差异要小得多。
我刚刚在 PHP 5.4.0 快照上测试了上面的代码,得到了以下结果:
with function call: 2.3795559406281
without function call: 0.90840601921082
这里的差异再次变大了(2.62)。 (但另一方面,这两种方法的执行时间都显着下降)。
【问题讨论】:
-
这是一个很大的假设。你有多确定 strlen 比 isset 重 30%?
-
做分析,而不是“基准”
-
@Col:如果你能告诉我在哪里可以找到负责此问题的代码,那就太好了。更好地解释哪些部分花费的时间最长。 (更清楚地说:我并不愚蠢。如果我知道负责的代码在那里,我就不会在这里问了。我在这里问是因为我不知道,我希望其他人知道.)
-
@Kendall:毕竟,你是对的。我刚刚在没有 XDebug 的情况下进行了测试,得到了非常不同的结果(见编辑)。非常感谢您指出。
-
作者现为PHP核心开发者。我希望这里的人们多一点理解,有时人们会问问题来学习。