Next generation's garbage RSS 2.0
# Saturday, November 10, 2007

Everyone knows exception handling is relatively expensive, but it is important to keep in mind where the cost lies. It is primarily in the throw action. The price of a try is nearly zero when no exceptions occur.

In the IL instruction stream the only difference between a wrapped block of code and plain is a LEAVE instruction that jumps around the catch block. The method has an exception table that marks the region of code protected. What happens when we actually time the difference? The result is extremely small -- and strangely enough, try/catch in the loop is slightly faster for C#! Because the numbers we are dealing with are so small, however, I would suggest that this is coincidental noise due to instruction alignment or something like that. I would guess that the cost of try is essentially crushed out by the JIT compiler optimizer.

The real expensive operation is throwing exceptions. How expensive? My tests show it's about 36 microseconds each. Slow by comparison, but maybe not as slow as you thought. As expected VB's exception handling was a little bit slower (~1%), due no doubt to SetProjectError calls that are inserted before throws/rethrows.

I always had an assumption that THROW (rethrow) was cheaper than THROW ex or THROW NEW. I reasoned that the stackframe would not have to be gathered during rethrow. Timing it shows rethrow is slightly slower.

I learned you have to be pretty careful about timing code. For example, a significant amount of time is burned JITing when a function is hit the first time, and that first exceptions are really expensive. Firsts should be burned off before timing begins.

Try out the code attached and post your results and please give environment.

Here's my numbers on a Dell Latitude D830 1.7GHz 64-bit laptop w/ 4GB RAM.

>CSharp.exe 10000000000 100000
trycount=10,000,000,000, throwcount=100,000
Loop without try/catch: 31132 milliseconds
Loop with try/catch: 21251 milliseconds
difference: -9881 milliseconds
throw new with 5 throw ex: 21448 milliseconds
throw new with 5 rethrows: 21370 milliseconds
difference: 78 milliseconds

>VB.exe 10000000000 100000
trycount=10,000,000,000, throwcount=100,000
Loop without try/catch: 23361 milliseconds
Loop with try/catch: 30739 milliseconds
difference: 7378 milliseconds
throw new with 5 throw ex: 21617 milliseconds
throw new with 5 rethrows: 21845 milliseconds
difference: -228 milliseconds

Attached: TestExceptionHandlingInLoop.rar (12.5 KB)
Saturday, November 10, 2007 1:59:25 PM (US Mountain Standard Time, UTC-07:00)  #    Comments [0] -
.NET Internals
<November 2007>
All Content © 2015, Hafthor Stefansson - Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way. - Sign In