gpt4 book ai didi

php - 为什么 PHP 函数调用如此昂贵?

转载 作者:IT王子 更新时间:2023-10-29 01:02:17 26 4
gpt4 key购买 nike

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)。 (但另一方面,这两种方法的执行时间都显着下降)。

最佳答案

函数调用在 PHP 中很昂贵,因为要完成很多事情。

请注意 isset 不是一个函数(它有一个特殊的操作码),所以它更快。

对于这样一个简单的程序:

<?php
func("arg1", "arg2");

有六个(四个+每个参数一个)操作码:

1      INIT_FCALL_BY_NAME                                       'func', 'func'2      EXT_FCALL_BEGIN                                          3      SEND_VAL                                                 'arg1'4      SEND_VAL                                                 'arg2'5      DO_FCALL_BY_NAME                              2          6      EXT_FCALL_END                                            

您可以在zend_vm_def.h 中检查操作码的实现。 .在名称前添加 ZEND_,例如ZEND_INIT_FCALL_BY_NAME 和搜索。

ZEND_DO_FCALL_BY_NAME 特别复杂。然后是函数本身的实现,它必须展开堆栈、检查类型、转换 zval 并可能将它们分开并投入实际工作...

关于php - 为什么 PHP 函数调用如此昂贵?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3691625/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com