Page 1 of 2

Performance implications of constructing an exception

Posted: Mon Sep 28, 2009 2:08 pm
by Ollie Saunders
I noticed that exceptions contain an entire stack trace, which can be a very large data structure when they are created.

Code: Select all

php > function foo() { return new Exception('meh'); }
php > var_dump(foo());
object(Exception)#2 (7) {
  ["message":protected]=>
  string(3) "meh"
  ["string":"Exception":private]=>
  string(0) ""
  ["code":protected]=>
  int(0)
  ["file":protected]=>
  string(14) "php shell code"
  ["line":protected]=>
  int(1)
  ["trace":"Exception":private]=>
  array(1) {
    [0]=>
    array(4) {
      ["file"]=>
      string(14) "php shell code"
      ["line"]=>
      int(1)
      ["function"]=>
      string(3) "foo"
      ["args"]=>
      array(0) {
      }
    }
  }
  ["previous":"Exception":private]=>
  NULL
}
 
Does anyone have any idea how costly that is, performance-wise?

Re: Performance implications of constructing an exception

Posted: Mon Sep 28, 2009 2:25 pm
by josh
Its not cheap, I'd recommend profiling memory with and without exceptions, you could grep out the throw lines ( I don't think having catch blocks matters unless they are actually thrown )

Re: Performance implications of constructing an exception

Posted: Mon Sep 28, 2009 5:38 pm
by alex.barylski
They might be expensive, but ask yourself, how many times or how often exceptions will actually be thrown?

For me, they occur and the application stops, it's not like there are 10 exceptions thrown in each invocation of every script.

Re: Performance implications of constructing an exception

Posted: Mon Sep 28, 2009 6:07 pm
by John Cartwright
It certainly would be interesting to see some benchmarks on exception usage, especially as some people tend to use them a bit excessively (myself included).

Re: Performance implications of constructing an exception

Posted: Mon Sep 28, 2009 6:14 pm
by Eran
For me, they occur and the application stops
+1

Re: Performance implications of constructing an exception

Posted: Mon Sep 28, 2009 7:12 pm
by Ollie Saunders
For me, they occur and the application stops, it's not like there are 10 exceptions thrown in each invocation of every script.
At one point, I was considering a course of action where exceptions would be thrown and caught, potentially, hundreds of times, which is why I made this thread. :-)

And, just to be clear, the stack trace is populated when the exception is constructed, it doesn't even have to be thrown.

Re: Performance implications of constructing an exception

Posted: Mon Sep 28, 2009 7:33 pm
by Eran
When would an exception be constructed and not thrown?

Re: Performance implications of constructing an exception

Posted: Mon Sep 28, 2009 10:03 pm
by Selkirk
I generally design things so that exceptions are ... exceptional. In the general course of servicing a request, I wouldn't instantiate even one on page returning a 200 status code.

the good news ... try {} is cheap. You only pay the price when you create the exception.

Re: Performance implications of constructing an exception

Posted: Tue Sep 29, 2009 6:36 am
by Ollie Saunders
When would an exception be constructed and not thrown?
If you are extending exceptions in some way (adding new functionality, for instance), then, testing that new functionality will involve instantiating the new extended exceptions without throwing them; the capability of being thrown doesn't need to be tested because it is implicit of any subclass of Exception.

At first sight of your question, I thought I'd be able to produce many acceptable answers. As it happens, I can only provide that one. This suggests that your question is good, but, because there is at least one, I don't consider it completely useless to know that the stack trace is populated at instantiation time. Maybe others can suggest more significance to the distinction between exception instantiation and throwing.

It is interesting though, the difficulty in answering that question tempts the possibility that a throw is merely a subtype of a normal return; anything that could be returned, could be thrown also:

Code: Select all

function throwingExplode($separator, $str) {
    $e = new Exception;
    $e->explosion = explode($separator, $str);
    throw $e; }
 
try { throwingExplode('/', 'foo/bar/zim'); } catch (Exception $e) { var_dump($e->explosion); }
PHP complicates things by requiring the-datum-being-thrown to be an instance of Exception. If that requirement wasn't present that last snippet might look like this:

Code: Select all

function throwingExplode($separator, $str) { throw explode($separator, $str); }
try { throwingExplode('/', 'foo/bar/zim'); } catch ($explosion) { var_dump($explosion); }
...which supports my assertion more obviously.

If this is the case, it might explain why it is so rarely required to merely return an exception. A throw will essentially do the same thing i.e. gets the Exception to you from inside whatever creates it.

Re: Performance implications of constructing an exception

Posted: Tue Sep 29, 2009 6:51 am
by Ollie Saunders
Now that I think about it PHP, could perceivably, have an even shorter syntax for returning thrown exceptions:

Code: Select all

var_dump(catch throwingExplode('/', 'foo/bar/zim'));
or possibly:

Code: Select all

var_dump(catch { throwingExplode('/', 'foo/bar/zim'); });
I don't see why "try" is necessary at all.

In Fluidics, I actually have a function that does this:

Code: Select all

var_dump(rescue('throwingExplode', array('/', 'foo/bar/zim'));

Re: Performance implications of constructing an exception

Posted: Tue Sep 29, 2009 10:37 am
by Eran
I think the try -> catch structure is more convention than necessity.

Regrading my question - I never considered testing exceptions separately from the actual throwing. I guess tests would incur the most impact from the performance implications of exceptions (as often they are thrown deliberately and many times in succession as you've suggested). I'm not sure if that's a concern for using them though - depends on how much of a hit it really is.

Re: Performance implications of constructing an exception

Posted: Tue Sep 29, 2009 12:07 pm
by Ollie Saunders
I think the try -> catch structure is more convention than necessity.
It's a syntactical requirement; catch may not appear without try.

Re: Performance implications of constructing an exception

Posted: Tue Sep 29, 2009 2:38 pm
by Eran
Obviously.. I meant for the PHP language to use this structure, it's more out of convention than any functional requirement. You were discussing possible alternative syntax, or so I understood

Re: Performance implications of constructing an exception

Posted: Tue Sep 29, 2009 3:11 pm
by Ollie Saunders
Oh right, yes. You saying "convention", confused me, because I don't associate language design with adhering to conventions, or even, many conventions existing across programming languages. But I see that is probably wrong, now.

Re: Performance implications of constructing an exception

Posted: Tue Sep 29, 2009 5:58 pm
by PHPHorizons
Ollie Saunders wrote:[snipped]I don't see why "try" is necessary at all.
Consider this:

Code: Select all

<?php
 
try {
  // some code that might thrown an exception.
   while (...) {
     // code in the while loop that could cause an exception, ending the loop.
     try {
         // code that should not end the while loop
     } catch (Exception $error) {
        // inner error handler (the loop could continue in the event of a not so exceptional exception)
     }
   } // end of while loop
 
} catch (Exception $error) {
   // The outer error handler. Catch exceptions that should end the while loop.
}
Without different try blocks, how would you know which catch should take precedence? It could always be assumed that the one closest to the exception is the one, but then you lose something don't you.

Hope that helps.