Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
223 views
in Technique[技术] by (71.8m points)

Why are PHP function calls *so* expensive?

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

<?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, "
";

// 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).

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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...


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...