views:

178

answers:

6

This is extremely slow:

try
{
    x = k / y;
}
catch (DivideByZeroException) { }

This is about 5x faster:

if (y > 0) x = k / y;

Can anybody tell me why?

+10  A: 

Because exceptions are expensive.

When an exception is thrown, the runtime needs to pick out quite a lot of information (stack traces for example) and bubble them up. This takes time and resources, when a test for 0 value is very cheap in comparison.

See this SO question asking how expensive exceptions are for more info.

Oded
+5  A: 

Err, because exceptions are slower than checking. Exceptions generally have a lot lot of infrastructure around them that a simple if statement doesn't.

They're not equivalent operations since you have a lot of information delivered in an exception even if you choose not to use it as in this case.

paxdiablo
+12  A: 

Only 5 times faster? You do surprise me. Presumably that means your sample data doesn't have many zeroes in it.

Exceptions are more expensive than simple comparisons. When used correctly (i.e. for exceptional circumstances) they don't tend to hamper performance significantly - because if you're throwing enough exceptions for it to make a big impact, chances are your service is already hosed. It does cause a problem when you use exceptions to try to ignore conditions which you could very easily test to start with - like this one.

One thing to note about the cost of exceptions: they cost a lot more in the debugger than when running without a debugger attached; in particular the first exception which needs to load a bunch of resources can take seconds rather than micro/milliseconds. If you're going to benchmark code, it's vital that you don't do it in a debugger - that's true in general, but particularly for exceptions.

Jon Skeet
+3  A: 

Why are exceptions slow?

Because a lot of stuff happens when an exception is thrown and caught. See Chris Brumme's post about the managed exception model and this post about the underlying Win32 SEH model for details.

Why is a simple test fast?

Because it just executes one instruction to jump depending on the result of the comparison of two integers which is much less work than an exception.

Does that mean I should always try to avoid exceptions?

No, it depends on semantics. If dividing by zero is a truly exception case that you do not expect to happen, and which your program cannot reasonably handle, then let the exception occur and crash your program. If, however, it's an expected case and you can handle it in a reasonable way then it would seem reasonable to avoid the exception.

Greg Beech
+2  A: 

Take a look at this articles:

Paulo Guedes
+1  A: 

Exceptions are extremely slow - This is the reason that the .Net framework has TryParse methods:

// This is much quicker...
double result;
if (!double.TryParse("Twelve", out result))
{
    result = -1;
}
return result;

// Than this...
try
{
    return double.Parse("Twelve");
}
catch 
{
    return -1;
}

you should always try and avoid exceptions (except for in exceptional circumstances - haha...)

Kragen