为什么PHP函数调用*如此昂贵? [英] Why are PHP function calls *so* expensive?

查看:93
本文介绍了为什么PHP函数调用*如此昂贵?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

PHP中的函数调用非常昂贵。这是测试它的一个小基准:



  //创建测试字符串
$ string = str_repeat('a',1000);
$ maxChars = 500;

//带函数调用
$ start = microtime(true); ($ i = 0; $ i< RUNS; ++ $ i){
strlen($ string)< = $ maxChars;
;

echo'with function call:',microtime(true) - $ start,\\\
;

//不带函数调用
$ start = microtime(true); ($ i = 0; $ i< RUNS; ++ $ i){
!isset($ string [$ maxChars]);

}
echo'without function call:',microtime(true) - $ start;

这首先使用函数测试功能相同的代码( strlen ),然后不使用函数( isset 不是函数)。



输出如下:

 带函数调用:4.5108239650726 
不带函数调用:0.84017300605774


$ b

正如你所看到的,使用函数调用的实现比不调用任何函数的实现慢5倍以上(5.38)倍。 p>

我想知道为什么函数调用非常昂贵。主要瓶颈是什么?它是哈希表中的查找吗?或者是什么这么慢?






我重新讨论了这个问题,并决定再次运行基准测试,XDebug完全禁用不只是分析禁用)。这表明,我的测试相当复杂,这次我得到了10000000次运行:

 带函数调用:3.152988910675 
没有函数调用:1.4107749462128

这里函数调用的速度大约是缓慢的两倍(2.23)所以差异就小得多了。




我刚刚在PHP 5.4.0快照上测试了上面的代码,以下结果:

 函数调用:2.3795559406281 
无函数调用: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 特别复杂。然后是函数本身的实现,它必须展开堆栈,检查类型,转换zvals并可能将它们分离并实际工作...


A function call in PHP is expensive. Here is a small benchmark to test it:

// 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;

This tests a functionally identical code using a function first (strlen) and then without using a function (isset isn't a function).

I get the following output:

with function call:    4.5108239650726
without function call: 0.84017300605774

As you can see the implementation using a function call is more than five (5.38) times slower than the implementation not calling any function.

I would like to know why a function call is so expensive. What's the main bottleneck? Is it the lookup in the hash table? Or what is so slow?


I revisited this question, and decided to run the benchmark again, with XDebug completely disabled (not just profiling disabled). This showed, that my tests were fairly convoluted, this time, with 10000000 runs I got:

with function call:    3.152988910675
without function call: 1.4107749462128

Here a function call only is approximately twice (2.23) as slow, so the difference is by far smaller.


I just tested the above code on a PHP 5.4.0 snapshot and got the following results:

with function call:    2.3795559406281
without function call: 0.90840601921082

Here the difference got slightly bigger again (2.62). (But on the over hand the execution time of both methods dropped quite significantly).

解决方案

Function calls are expensive in PHP because there's lot of stuff being done.

Note that isset is not a function (it has a special opcode for it), so it's faster.

For a simple program like this:

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

There are six (four + one for each argument) opcodes:

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                                            

You can check the implementations of the opcodes in zend_vm_def.h. Prepend ZEND_ to the names, e.g. for ZEND_INIT_FCALL_BY_NAME and search.

ZEND_DO_FCALL_BY_NAME is particularly complicated. Then there's the the implementation of the function itself, which must unwind the stack, check the types, convert the zvals and possibly separate them and to the actual work...

这篇关于为什么PHP函数调用*如此昂贵?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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