Checking the performance of PHP exceptions


Sometimes we use exceptions to manage the flow of our scripts. I imagine that the use of exceptions must have a performance lack. Because of that I will perform a small benchmark to test the performance of one simple script throwing exceptions and without them. Let’s start:

First a silly script to find even numbers (please don’t use it it’s only for the benchmanrk :) )

error_reporting(-1);
$time = microtime(TRUE);
$mem = memory_get_usage();

$even = $odd = array();
foreach (range(1, 100000) as $i) {
  try {
    if ($i % 2 == 0) {
      throw new Exception("even number");
    } else {
      $odd[] = $i;
    }
  } catch (Exception $e) {
    $even[] = $i;
  }
}
echo "odds: " . count($odd) . ", evens " . count($even);
print_r(array('memory' => (memory_get_usage() - $mem) / (1024 * 1024), 'microtime' => microtime(TRUE) - $time));

And now the same script without exceptions.

error_reporting(-1);
$time = microtime(TRUE);
$mem = memory_get_usage();

$even = $odd = array();
foreach (range(1, 100000) as $i) {
    if ($i % 2 == 0) {
        $even[] = $i;
    } else {
        $odd[] = $i;
    }
}

echo "odd: " . count($odd) . ", evens " . count($even);
print_r(array('memory' => (memory_get_usage() - $mem) / (1024 * 1024), 'microtime' => microtime(TRUE) - $time));

The outcomes:
with exceptions
memory: 10.420181274414
microtime: 1.1479668617249 0.19249302864075 (without xdebug)

without exceptions
memory: 10.418941497803
microtime: 0.14752888679505 0.1234929561615

As we can see the use of memory is almost the same and ten times faster without exceptions.

I have done this test using a VM box with 512MB of memory and PHP 5.3.
Now we are going to do the same test with a similar host. The same configuration but PHP 5.4 instead of 5.3

PHP 5.4:
with exceptions
memory: 7.367259979248
microtime: 0.1864490332

without exceptions
memory: 7.3669052124023
microtime: 0.089046955108643

I’m really impressed with the outcomes. The use of memory here with PHP 5.4 is much better now and the execution time better too (ten times faster).

According to the outcomes my conclusion is that the use of exceptions in the flow of our scripts is not as bad as I supposed. OK in this example the use of exceptions is not a good idea, but in another complex script exceptions are really useful. We also must take into account the tests are iterations over 100000 to maximize the differences. So I will keep on using exceptions. This kind of micro-optimization not seems to be really useful. What do you think?

About these ads

About Gonzalo Ayuso

Web Architect specialized in Open Source technologies. PHP, Python, JQuery, Dojo, PostgreSQL, CouchDB and node.js but always learning.

Posted on January 16, 2012, in micro-optimizations, php, Technology and tagged , , , , . Bookmark the permalink. 12 Comments.

  1. I never thought of native Exception handling causing a performance penalty. Thank you for the benchmarks, they show that the difference is negligible. The great news is the performance boost of PHP 5.4.

  2. It would be better throw errors to compare with the exceptions.

  3. Thank you for that benchmark, interesting information! Hope 5.4 will arrive soon!

  4. I ran the benchmark on my machine, but to test is_int versus modulus (as I was once told in an interview that modulus was computationally expensive and asked if there was another way to determine if a number was even, and your post reminded me to check out the claim).

    It’s a Windows 7 machine, running PHP 5.3 from the commandline. Memory use, using your same function, without exceptions, was 0.8258 or about 1/9th of what you were getting

    BTW, is_int ran in 0.00463 while modulus ran in 0.00272.

  5. I got more optimistic results. Using Ubuntu and php 5.3.6:

    with exceptions
    microtime: 0.44

    without exceptions
    microtime: 0.12

  6. What an awful comparison to make. The only conclusion here is that Exceptions take time. Hardly a surprising outcome considering what Exceptions are and what they do.

  7. No surprise here. Of course exception handling is more expensive than doing a simple comparison with an if. PHP needs to create the try environment, instantiate the exception, invoke the exception handler and then check all the possible catch blocks whether they can catch the thrown exception type. Assuming this would be anywhere close in speed to a simple if/else comparison is naive. General control flow should not be handled with exceptions at all. Exceptions are for exceptional cases in your code.

    • I’m agree with you. I’ve done this benchmark to chek if exception performance is good enought (obviouslyit must be worse than if statements because of the facts you said). As I can see they are good enought. Of course if we can avoid then it’s better, but if we need them we can use them without problems

  8. A quick tip for the next time when you do “benchmarking”: Try to understand the reason behind it.

    For example here the reason is that you did your PHP 5.3 benchmarking with XDebug enabled, and the PHP 5.4 benchmarking with XDebug disabled.

    With XDebug (5.3.8) the Exception code needs 1.2 seconds on my machine.
    Without it (still 5.3.8) it needs only 0.14 seconds.
    On 5.4RC3 (without XDebug) it needs 0.09. So the improvement is actually quite minimal (only factor of two).

    So, next time you do benchmarks, don’t forget to disabled XDebug ;)

    • Interesting. I’m quite sure xdebug is not enabled in PHP5.4 but not 100% sure if it’s enabled within 5.3. I will check it and post it too.

  9. What if you create the exception object *outside* the loop:

    $e = new Exception(“even number”);

    foreach (range(1, 100000) as $i)
    {
    try {
    if ($i % 2 == 0) {
    throw $e
    } else {
    $odd[] = $i;
    }
    } catch (Exception $e) {
    $even[] = $i;
    }
    }

    Because to me what your are testing is mostly the cost of creating objects.

  10. Acording to the last comments (thanks :) ) I’ve got two conclusions:
    First disable xdebug in the benchmarks. xdebug gives us great tools in our development environment, but with an extra fee. Without xdebug the performance gain is not so expectacular between 5.3 and 5.4, but it’s better with 5.4 indeed.

    Second one is the miliseconds that we loose with exceptions are mostly because of the cost of create object.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 1,003 other followers

%d bloggers like this: