Pragmatism in the real world

PHP 5.3 is quicker than PHP 5.2

I know that everyone already knows this, but I happened to find out for myself recently!

I was looking at the way view helpers work in ZF2 and thought it would be more convenient if we altered the syntax a little. A side-effect of the change was that we’d have to use call_user_func_array, which is perceived as slow. I thought I’d whip up a simple test to find out how much slower it would be over a direct method call.

That is, how much slower is this code:
$a = new A();
call_user_func_array(array($a, 'b'), array(1));

than this code:
$a = new A();
$a->b(1);

Bear in mind that I don’t do formal benchmarks and have no clue on methodology. Paul Jones is your man for proper testing of performance.

With that caveat out of the way this is the code I wrote to test:

benchmark.php

<?php

class A
{
function b($a)
{
return;
}
}

define ('ITERATIONS', 10000000);
$start = microtime(true);
$a = new A();
for ($i = 0; $i < ITERATIONS; ++$i) {
$a->b(1);
}
$stop = microtime(true);
echo 'Direct method call: ' . ($stop - $start) . ' seconds' . PHP_EOL;

$start = microtime(true);
for ($i = 0; $i < ITERATIONS; ++$i) {
call_user_func_array(array($a, 'b'), array(1));
}
$stop = microtime(true);
echo 'call_user_func_array call: ' . ($stop - $start) . ' seconds' . PHP_EOL;

This was the simplest possible scenario I could imagine and so would show call_user_func_array in the best possible light.

I ran the test on my laptop (using the command line) and got these results:


Direct method call: 21.155211925507 seconds
call_user_func_array call: 72.147792100906 seconds

i.e. call_user_func_array is around 3.5 times slower over 10 million iterations.

Nobody uses their laptop to serve a website though! Being the curious sort, I thought I’d test the difference of this script between PHP 5.2 and PHP 5.3 in a completely unscientific way as I’m lazy! I happen to have a server with both PHP 5.2 and PHP 5.3. on it, so I used that:

PHP 5.2:

Direct method call: 8.3424661159515 seconds
call_user_func_array call: 26.904649972916 seconds

PHP 5.3:

Direct method call: 3.35181903839 seconds
call_user_func_array call: 11.5989868641 seconds

As you can see, my server is much faster than my laptop :) Also, the relative difference is the same. i.e. PHP 5.3’s call_user_func_array is as slow as it is in PHP 5.2.

I think I’ll move everything to PHP 5.3 for the free performance gain! Of course, The question remains as to whether we should avoid call_user_func_array or not.

I would however recommend testing your own apps and see if it makes any difference and please don’t take this post as anything other than something interesting I found out!

8 thoughts on “PHP 5.3 is quicker than PHP 5.2

  1. In my opinion array initalization is a main performance problem. Try to move array initialization out of the loop

    $t1 = array($a, 'b');
    $t2 = array(1);
    for ($i = 0; $i < ITERATIONS; ++$i) {
    call_user_func_array($t1, $t2);
    }

    then your test should be more precise.

  2. pc:

    I've altered as you said. These are the numbers:

    PHP 5.2:
    Direct method call: 8.9717271327972 seconds
    call_user_func_array call: 22.13850903511 seconds

    PHP 5.3:
    Direct method call: 6.423406124115 seconds
    call_user_func_array call: 20.517752170563 seconds

    So, there is a little saving of time.

    Regards,

    Rob…

  3. Correct me if I'm wrong, but if your second set of results are accurate then moving array initialisation out of the loop in this case is more expensive in PHP5.3?

    PHP 5.2:

    Direct method call: 8.9717271327972 seconds
    call_user_func_array call: 22.13850903511 seconds

    PHP 5.3:

    Direct method call: 6.423406124115 seconds
    call_user_func_array call: 20.517752170563 seconds

  4. this is the same sort of argument as $i++ vs ++$i

    var_dump(round(6.423406124115 / 10000000, 5));

    var_dump(round(20.517752170563 / 10000000, 5));

    and then ask yourself, do you really care? if you are calling something 10 million times you are doing it wrong.

  5. Thanks Rob, I wasn't expecting a difference so evident…
    @dogmatic69 I assume this test is related to frameworks, where call_user_func* functions are extensively used to provide flexibility ;)

  6. Thanks Rob, I wasn't expecting a difference so evident… @dogmatic69 I assume this test is related to frameworks, where call_user_func* functions are extensively used to provide flexibility ;)

Comments are closed.