This debate goes around in circles in the C# community. I have seen several C# programmers struggle with the use of exceptions. If not used correctly, exceptions can slow down your program, as it takes memory and CPU power to create, throw, and catch exceptions.
Exceptions are expensive, but there is more to it when you want to choose between exception and return codes. Historically speaking the argument was: exceptions ensure that code is forced to handle the situation whereas return codes can be ignored.
If you have performance problems due to exceptions, it isn't just that the exception is slow, it is that you're throwing way too many of them. In other words, if you're using exceptions correctly, to indicate exceptional problems, then you shouldn't have to bother.
So, yes, exceptions are slow on the exceptional path, but they are otherwise quicker than explicit checks ( if strategy) in general.
I'm on the "not slow" side - or more precisely "not slow enough to make it worth avoiding them in normal use". I've written two short articles about this. There are criticisms of the benchmark aspect, which are mostly down to "in real life there'd be more stack to go through, so you'd blow the cache etc" - but using error codes to work your way up the stack would also blow the cache, so I don't see that as a particularly good argument.
Just to make it clear - I don't support using exceptions where they're not logical. For instance, int.TryParse
is entirely appropriate for converting data from a user. It's appropriate when reading a machine-generated file, where failure means "The file isn't in the format it's meant to be, I really don't want to try to handle this as I don't know what else might be wrong."
When using exceptions in "only reasonable circumstances" I've never seen an application whose performance was significantly impaired by exceptions. Basically, exceptions shouldn't happen often unless you've got significant correctness issues, and if you've got significant correctness issues then performance isn't the biggest problem you face.
There is the definitive answer to this from the guy who implemented them - Chris Brumme. He wrote an excellent blog article about the subject (warning - its very long)(warning2 - its very well written, if you're a techie you'll read it to the end and then have to make up your hours after work :) )
The executive summary: they are slow. They are implemented as Win32 SEH exceptions, so some will even pass the ring 0 CPU boundary! Obviously in the real world, you'll be doing a lot of other work so the odd exception will not be noticed at all, but if you use them for program flow expect your app to be hammered. This is another example of the MS marketing machine doing us a disservice. I recall one microsoftie telling us how they incurred absolutely zero overhead, which is complete tosh.
Chris gives a pertinent quote:
In fact, the CLR internally uses exceptions even in the unmanaged portions of the engine. However, there is a serious long term performance problem with exceptions and this must be factored into your decision.
I have no idea what people are talking about when they say they are slow only if they are thrown.
EDIT: If Exceptions aren't thrown, then that means you are doing new Exception() or something like that. Otherwise the exception is going to cause the thread to be suspended, and the stack to be walked. This may be Ok in smaller situations, but in high-traffic websites, relying on exceptions as a workflow or execution path mechanism will certainly cause you performance problems. Exceptions, per se, aren't bad, and are useful for expressing exceptional conditions
The exception workflow in a .NET app uses first and second chance exceptions. For all exceptions, even if you are catching and handling them, the exception object is still created and the framework still has to walk the stack to look for a handler. If you catch and rethrow of course that is going to take longer - you are going to get a first-chance exception, catch it, rethrow it, causing another first-chance exception, which then doesn't find a handler, which then causes a second-chance exception.
Exceptions are also objects on the heap - so if you are throwing tons of exceptions, then you are causing both performance and memory issues.
Furthermore, according to my copy of "Performance Testing Microsoft .NET Web Applications" written by the ACE team:
"Exception handling is expensive. Execution of the involved thread is suspended while CLR recurses through the call stack in search of the right exception handler, and when it is found, the exception handler and some number of finally blocks must all have their chance to execute before regular processing can be performed."
My own experience in the field showed that reducing exceptions significantly helped performance. Of course, there are other things you take into account when performance testing - for example, if your Disk I/O is shot, or your queries are in the seconds, then that should be your focus. But finding and removing exceptions should be a vital part of that strategy.
The argument as I understand it is not that throwing exceptions are bad they are slow per se. Instead, it is about using the throw/catch construct as a first class way of controlling normal application logic, instead of more traditional conditional constructs.
Often in normal application logic you perform looping where the same action is repeated thousands/millions of times. In this case, with some very simple profiling (see the Stopwatch class), you can see for yourself that throwing an exception instead of say a simple if statement can turn out to be substantially slower.
In fact I once read that the .NET team at Microsoft introduced the TryXXXXX methods in .NET 2.0 to many of the base FCL types specifically because customers were complaining that performance of their applications was so slow.
It turns out in many cases this was because customers were attempting type conversion of values in a loop, and each attempt failed. An conversion exception was thrown and then caught by an exception handler that then swallowed the exception and continued the loop.
Microsoft now recommend the TryXXX methods should be used particularly in this situation to avoid such possible performance issues.
I could be wrong, but it sounds like you are not certain about the veracity of the "benchmarks" you have read about. Simple solution: Try it out for yourself.
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