views:

660

answers:

11

Possible Duplicate:
Do try/catch blocks hurt performance when exceptions are not thrown?

Hey everyone, Just a quick question about try..catch blocks. I've heard they're expensive to use and shouldn't be used as part of a program's flow. However, in order to validate email addresses, I'm using the following code.

        try
        {
            MailAddress checkEmail = new MailAddress(testEmail);

            return true;
        }
        catch
        {
            return false;
        }

Due to prior validation, I don't many exceptions to be caught unless it's an attempt to bypass validation. My question is, are Try...Catch blocks only expensive if an exception is caught, or is it always expensive regardless of whether any exception is thrown?

Thanks

EDIT : Thanks for all the replies. I've decided that since the checking (in C#) isn't very expensive, I'll stick with this method. It's mainly because an actual exception being thrown is rare since there are prior validation steps that ensure no one accidentally enters an invalid email address.

+2  A: 

HERE is a great read on try catch blocks and performance hits.

gmcalab
+2  A: 

try..catch blocks should never be used as a tool for program flow control.

Read this thread if you're unconvinced.

Kornel Kisielewicz
+1  A: 

They are pretty cheap unless there is an exception. So you should avoid them when an exception is expected, as in your example above.

I think exceptions on bad user input are generally unwise. Exceptions on out of memory or other unexpected failures are fine.

John Knoeller
The input is validated normally using regular expressions. However, if someone has purposely bypassed the validation (by tampering the POST header), this exception is potentially thrown.
Skoder
It's a judgement call. But I'd say that's sufficiently exceptional.
John Knoeller
A: 

In general, modern compilers impose only a minimal cost on try blocks unless an exception is thrown. They still shouldn't be used for program flow control, as they aren't as obvious as standard flow constructs. An exception is essentially equivalent to a COME FROM statement.

David Thornley
+1  A: 

Exceptions are only expensive if an exception is thrown. I'm sure there is some very minimal cost to setting up up a Try..Catch block but it is by far outweighed by the cost of not catching the exception at all and having your program crash. As others have pointed out, Try..Catch blocks should only be used for exceptional circumstances.

TLiebe
A: 

While it is true that you should never use try..catch for program flow control, I am not aware of any performance issues IF no exceptions are actually thrown in the code

Sands
+8  A: 

It's very hard to answer this question without your having mentioned what environment you're talking about (Java, C#, ...).

In general, in today's implementations, entering a try block is not expensive at all (this was not always true). However, throwing and handling an exception is usually an expensive operation. So, exceptions should only be used for exceptional events. For example, when you're opening a file that a user has given the path for, use whatever your environment provides to check first whether the file exists, even if the "open" operation will throw a FileNotFoundException or similar if it doesn't. The check will be cheap; processing the exception may not be.

T.J. Crowder
Hi, sorry I thought I tagged C#. I've fixed it now. I only expect the exception to be thrown if a user has purposely tampered with the POST header since standard validation is applied on the input.
Skoder
Very nicely put answer @T.J. I'd also add with regard to the performance hit when handling an exception, don't forget that at that point the application has stopped behaving as expected (i.e. the proverbials have hit the fan), indicating a bigger issue that needs to be resolved, therefore performance probably isn't such a big concern at that point. This of course follows T.J.'s point of "exceptions should only be used for exceptional events" - something I still find many developers don't appreciate.
Jason Snelders
Since when is opening a file a performance-critical operation? IMHO try-catch is more readable in this case and the performance difference is negligible compared to the overall complexity of the operation.
dsimcha
@dsimcha: That's fine, although if you find simple if statements hard to read... ;-) I've worked with frameworks where an exception (the first exception of a given type) would cause 2-3 second pauses resulting in a degraded user experience; opening a local file is a dramatically sub-second operation.
T.J. Crowder
@T.J. Crowder: What kind of horribly defective framework would make it take this long to create an exception? Yes, exceptions are slow, but I thought slow meant on the order of tens or hundreds of thousands of CPU cycles, not billions (assuming modern hardware).
dsimcha
@dsimcha: That particular example was a .Net 1.1 "rich web client;" thankfully we finally got that customer upgraded to something more recent. Happened both when run via NTD and as a local executable. But leaving that aside, for user-supplied paths I'd definitely check before opening (whereas I don't if the code should be able to expect it to be there), since one of the normal cases is that the file is not there; otherwise, maintenance coders have to go scrolling down and point through your exception-handling code to find out what you do for this (to my mind) non-exceptional condition.
T.J. Crowder
A: 

This is language-dependent, but as far as I know in Java, if no exception is thrown, there is next to no performance cost to having a try/catch.

So in your example of using pre-validated email addresses, what you have is fine.

Chris Jester-Young
Thanks. I'm using C# (I've fixed the tag). I assume that it's a similar thing in C# as it is in Java. I am using a pre-validated email address to ensure integrity, but this is always called regardless.
Skoder
+1  A: 

The overhead of the try block is very low, so if no exception is thrown then there should be no noticeable penalty. The main overhead that occurs when an exception is thrown is the stack walk that takes place looking for a handler - since you are caching the exception so close to the source, I doubt there will be much of a performance issue. Ideally though you would be able to validate your inputs properly beforehand, but email validation is fairly complicated so it may well not be worth it in this case.

Lee
+1  A: 
dferraro
I don't get it?
Kornel Kisielewicz
It's a way to implement the 'cancel' button / functionality of some job that a user can execute. This job can take hours to run given the right params. I Log() at each different step anyway to give user feedback. So each time I log, I check a hasCancelled field and if it's true, I throw a JobCancelledException. Now, no matter where we are in the code, the job will stop immediately, as I handle this exception at the highest level of the call stack. Super simple and works great.
dferraro
+1  A: 

It's only expensive if the exception is thrown, but that's not an excuse to use exceptions as normal flow control.

If you can pre-validate something to avoid an exception occurring in the first place, then do so. E.g. instead of what you posted, something like this would be preferable:

string invalidAddress = "notvalid@@@@@@lolzors.bomb";
return MailAddressValidator.IsValid(invalidAddress ); // doesn't cause exception

The exception to the rule is when you'd have to roll your own version of a complicated method (e.g. something found in the base class library that doesn't have a TryParse method) just to avoid an exception that, in the grand scheme of things, just doesn't matter.

If you are unsure, profile using representative data. If it's a user entering data in a client app form every other second, it won't matter. However, if it's a service for processing batches of thousands of email addresses that could come from anywhere, you ought to be sure of your assumptions.

Mark Simpson