error checking keys when iterating over a dictionary

Published / by Tristen Horton / Leave a Comment

I’ve never been one for caring about the performance cost of iteration so much. Some developers on #c-sharp brought up the performance of Try Catch and accessing items in a collection like a Dictionary, this peaked my interest. I decided to experiment.

When accessing an item in a Dictionary, an exception is thrown if a non-existent key is passed. To avoid this, the typical thing to do is one of three solutions:

I decided to benchmark each solution to determine which has better performance. The consensus was that the Try Catch Finally solution was going to be very slow compared to ContainsKey and TryGetValue, and that ContainsKey will be slower than TryGetValue. Let’s test this theory.

TL;DR

TryGetValue seems to be the most time-efficient solution for a Dictionary collection, and Try Catch Finally is good if your project depends more on Exceptions for errors than it relies on being fast. Equivalent functions for other collection types may be analogous in speed.

If you want to know the approximate differences, read below.

The Test

My benchmark test recreated a dictionary every time the expected number of items increased during each iteration. I proceeded to iterate over the dictionary 1000 times per method, and averaged out the time it took per item.

The graph below is a logarithmic scale of the time it takes to access an item in a Dictionary, on average, versus the number of items in the collection.

ContainsKey vs TryGetValue vs TryCatchFinally

ContainsKey vs TryGetValue vs TryCatchFinally (click to enlarge)

What do all these lines mean? Somewhat conclusively that Try Catch Finally and TryGetValue are comparably faster than ContainsKey.

If your project depends heavily on Exceptions for error handling, then that slight difference in speed between TryCatchFinally and TryGetValue probably doesn’t matter. Otherwise, TryGetValue is the way to go!

This got me thinking though… What if I do in fact pass a key that isn’t present in my Dictionary? Does that effect performance whatsoever?

Here is the data for each of the methods, using only keys that don’t exist, on similar logarithmic scales:

ContainsKey Hits and Misses

ContainsKey hits and misses (click to enlarge)

TryGetValue Hits and Misses

TryGetValue hits and misses (click to enlarge)

TryCatchFinally Hits and Misses

TryCatchFinally hits and misses (click to enlarge)

The differences between Hit and Miss performance are negligible. So boring 🙁

So at least my previous statement about TryGetValue and Try Catch Finally still stands.

The Code