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:
