Coder Perfect

Why is checking if the dictionary contains the key faster than catching the exception if it doesn’t?

Problem

Imagine the code:

public class obj
{
    // elided
}

public static Dictionary<string, obj> dict = new Dictionary<string, obj>();

Method 1

public static obj FromDict1(string name)
{
    if (dict.ContainsKey(name))
    {
        return dict[name];
    }
    return null;
}

Method 2

public static obj FromDict2(string name)
{
    try
    {
        return dict[name];
    }
    catch (KeyNotFoundException)
    {
        return null;
    }
}

I was curious if there was a performance difference between these two functions, because the first one SHOULD be SLOWER than the second, given that it needs to check twice if the dictionary contains a value, whereas the second function only needs to access the dictionary once, but WOW, it’s the exact opposite:

Loop for 1000000 values (with 100000 already present and 900000 not yet present):

Why is that?

EDIT: As you can see from the comments below this question, the second function performs significantly better than the first when there are no non-existing keys. However, once there are one or more non-existing keys, the performance of the second one rapidly degrades.

Asked by Petr

Solution #1

Throwing exceptions, on the one hand, is fundamentally expensive because the stack must be unwound, and so on. Accessing a value in a dictionary by its key, on the other hand, is inexpensive because it is a fast, O(1) operation.

BTW, TryGetValue is the correct way to do this.

obj item;
if(!dict.TryGetValue(name, out item))
    return null;
return item;

Instead of accessing the dictionary twice, this method only does so once. If you absolutely want to just return null if the key doesn’t exist, you can simplify the code even more:

obj item;
dict.TryGetValue(name, out item);
return item;

Because TryGetValue sets item to null if no key with the name exists, this works.

Answered by Daniel Hilgarth

Solution #2

The purpose of dictionaries is to perform super-fast key lookups. They’re implemented as hashtables, and the more entries they have, the faster they’ll be in comparison to other techniques. Because it is a vast group of objects with a lot of capability for handling failures, using the exception engine should only be done when your method has failed to perform what you intended it to do. I once developed a whole library class, enclosing everything in try catch blocks, and was shocked to see the debug output, which comprised a separate line for each of the over 600 exceptions!

Answered by Ed Hermanson

Post is based on https://stackoverflow.com/questions/16101795/why-is-it-faster-to-check-if-dictionary-contains-the-key-rather-than-catch-the