I have come across the following type of code many a times, and I wonder if this is a good practice (from Performance perspective) or not:
try
{
... // some code
}
catch (Exception ex)
{
... // Do something
throw new CustomException(ex);
}
Basically, what the coder is doing is that they are encompassing the exception in a custom exception and throwing that again.
How does this differ in Performance from the following two:
try
{
... // some code
}
catch (Exception ex)
{
.. // Do something
throw ex;
}
or
try
{
... // some code
}
catch (Exception ex)
{
.. // Do something
throw;
}
Putting aside any functional or coding best practice arguments, is there any performance difference between the 3 approaches?
If these exceptional conditions are not properly caught and handled, they can cause an error or failure in the system. Failures due to exceptions are estimated to account for two thirds of system crashes and fifty percent of system security vulnerabilities [Maxion98].
In the paper Efficient Java exception handling in just-in-time compilation, the authors suggest that the presence of exception handlers alone, even if no exceptions are thrown, is enough to prevent the JIT compiler from optimizing the code properly, thus slowing it down.
In general, wrapping your Java code with try/catch blocks doesn't have a significant performance impact on your applications. Only when exceptions actually occur is there a negative performance impact, which is due to the lookup the JVM must perform to locate the proper handler for the exception.
Another way to avoid exceptions is to return null (or default) for most common error cases instead of throwing an exception. A common error case can be considered a normal flow of control. By returning null (or default) in these cases, you minimize the performance impact to an app.
@Brad Tutterow
The exception is not being lost in the first case, it is being passed in to the constructor. I will agree with you on the rest though, the second approach is a very bad idea because of the loss of stack trace. When I worked with .NET, I ran into many cases where other programmers did just that, and it frustrated me to no end when I needed to see the true cause of an exception, only to find it being rethrown from a huge try block where I now have no idea where the problem originated.
I also second Brad's comment that you shouldn't worry about the performance. This kind of micro optimization is a HORRIBLE idea. Unless you are talking about throwing an exception in every iteration of a for loop that is running for a long time, you will more than likely not run into performance issues by the way of your exception usage.
Always optimize performance when you have metrics that indicate you NEED to optimize performance, and then hit the spots that are proven to be the culprit.
It is much better to have readable code with easy debugging capabilities (IE not hiding the stack trace) rather than make something run a nanosecond faster.
A final note about wrapping exceptions into a custom exception... this can be a very useful construct, especially when dealing with UIs. You can wrap every known and reasonable exceptional case into some base custom exception (or one that extends from said base exception), and then the UI can just catch this base exception. When caught, the exception will need to provide means of displaying information to the user, say a ReadableMessage property, or something along those lines. Thus, any time the UI misses an exception, it is because of a bug you need to fix, and anytime it catches an exception, it is a known error condition that can and should be handled properly by the UI.
Obviously you incur in the penalty of creating new objects (the new Exception) so, exactly as you do with every line of code that you append to your program, you must to decide if the better categorization of exceptions pays for the extra work.
As a piece of advice to make that decision, if your new objects are not carrying extra information about the exception then you can forget constructing new exceptions.
However, in other circumstances, having a hierarchy of exceptions is very convenient for the user of your classes. Suppose you're implementing the Facade pattern neither of the so far considered scenarios is good:
In this hypothetical case, the better thing to do is to create a hierarchy of exception classes that, abstracting your users from the inner complexities of the system, allows them to know something about the kind of exception produced.
As a side note:
I personally dislike the use of exceptions (hierarchies of classes derived from the Exception class) to implement logic. Like in the case:
try {
// something that will raise an exception almost half the time
} catch( InsufficientFunds e) {
// Inform the customer is broke
} catch( UnknownAccount e ) {
// Ask for a new account number
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With