Avoid functions for maximum performance

Calling a function in PHP is very expensive, so avoid it whenever you can. There are two methods for accomplishing this - one for user functions, and one for built-ins.

If you are calling a user function that is quite short, consider inlining it. This is a technique employed in C and C++ that essentially copies the contents of a function to wherever it was called, thus avoiding the function call. Consider the following code example:

<?php
    
function some_func() {
        
$j = 1;
    }

    
$START = time();
    for (
$i = 0; $i < 4000000; ++$i) {
        
some_func();
    }
    
$END = time() - $START;
    echo
"Calling the function took $END seconds\n";

    
$START = time();
    for (
$i = 0; $i < 4000000; ++$i) {
        
$j = 1;
    }
    
$END = time() - $START;
    echo
"Inlining took $END seconds\n";
?>

As you can see, the function call is quite simple - only one line, with no parameters being passed in and no return value being use. On my test machine, the first loop took 15 seconds and the second loop to just 5 seconds. Having longer functions decreases the impact of function calls, but adding parameters and return values will increase it. For example, editing the above script so that some_func() takes just two parameters (although the function did not use them) increased the function loop execution time to 30 seconds - a huge difference from the 5 seconds with inlining.

For built-in functions, your only choice is to try to live without the function call. It is never better to try to rewrite a built-in function using PHP so that you can inline it, as the built-in function uses highly optimised C code that is likely to be as fast as it can get. However, there are some functions you can live without quite easily, such as floor(). This function rounds a floating-point number down to the nearest integer, which is also what typecasting a float to an integer does. In this situation, typecasting a floating-point number to an integer as opposed to using floor() is about a third faster, so it's best to avoid floor() in tight loops.

Author's Note: Above and beyond all the other performance tweaks presented here, this one is definitely one best left until the very end - if you really need that extra bit of performance. Functions are there to centralise code and are incredibly helpful, and inlining them before you really need to definitely counts as premature optimisation. To be absolutely clear: please, go ahead and use all the functions you want. You should only start to scale back a little if you're struggling to get the performance you need and have exhausted all other possibilities.

Eric Raymond, in his marvellous book "The Art of Unix Programming" (available online at this link but really worth buying), has a wonderful quote from Steve Johnson, an early Unix hacker responsible (amongst other things) for the Portable C Compiler and Yacc. The quote is this: "Dennis Ritchie encouraged modularity by telling all and sundry that function calls were really, really cheap in C. Everybody started writing small functions and modularizing. Years later we found out that function calls were still expensive on the PDP-11, and VAX code was often spending 50% of its time in the CALLS instruction. Dennis had lied to us! But it was too late; we were all hooked..."

Expensive, yes, and expensive still, but there's a reason using functions is so addictive!

 

Next chapter: Use the Zend Optimizer >>

Previous chapter: Use your tools wisely

Jump to:

 

Home: Table of Contents

Follow us on Identi.ca or Twitter

Username:   Password:
Create Account | About TuxRadar