Chinh Do

Try/Catch Blocks Can Hurt Performance Significantly

First time here? Check out my greatest hits or look around in the archives, and consider subscribing to the latest posts via RSS or email. Thanks for visiting.
26th February 2008

Try/Catch Blocks Can Hurt Performance Significantly

Over at Programmers Heaven.com, there’s an interesting article on the potential performance impact of try/catch blocks. The article concluded that the average cost of a try/catch block is essentially nothing (sorry there’s no author information on the post so I couldn’t tell who wrote it), and that .NET/C# programmers should not think twice about using try/catch blocks.

The author is right that a try/catch block has essentially zero cost. However, like most coding performance issues, exceptions and try/catch blocks do not have performance implications until they occur in some type of loop. Something like this will do the job:

Dictionary<int, int> numbers = new Dictionary<int, int>();
Stopwatch w = new Stopwatch();
w.Start();
int notFound = 0;
for (int i = 1; i <= 1000000; i++)
{
    try
    {
        int value = numbers[i];
    }
    catch (KeyNotFoundException)
    {
        notFound++;
    }
}

w.Stop();
Console.WriteLine(notFound);
Console.WriteLine("Elapsed: " + w.ElapsedMilliseconds + ".");

In the block of code above, I am trying to find the number of integers from 1 to 1,000,000 that are not in the numbers dictionary. One way to do it is to try to access the dictionary item by key. Since the Dictionary class will throw a KeyNotFoundException if the key is not found, that’s how I am going to know whether each value is in the dictionary or not.

Well, let’s just see how long that code takes to run. On my virtual PC it took … hold on a sec, it’s till running… still waiting… not quite there yet… finally: 101031 (101 seconds).

If you have any doubt, this is the type of try/catch block or exception handling they advice against. :-)

The above logic, when implemented correctly without using a try/catch block, took only 10 milliseconds. Yes, that’s not a typo: 10 milliseconds. Oh, only about 10,000 times faster.

Here’s the correct code:

Dictionary<int, int> numbers = new Dictionary<int, int>();

Stopwatch w = new Stopwatch();
w.Start();

int notFound = 0;
for (int i = 1; i <= 1000000; i++)
{
    if (! numbers.ContainsKey(i))
    {
        notFound++;
    }
}

w.Stop();
Console.WriteLine(notFound);
Console.WriteLine("Elapsed: " + w.ElapsedMilliseconds + ".");

So, do consider performance impact when using exceptions and try/catch blocks. Avoid using exception handling to implement normal program flow. Here are some links on exception handling best practices in .NET:

kick it on DotNetKicks.com

posted in Dotnet/.NET - C#, Programming | 22 Comments