Coming from a gamedev perspective, if your key is a value type (struct, primitive, enum, etc.) providing your own EqualityComparer<T> is significantly faster - due to the fact the EqualityComparer<T>.Default boxes the value.

As a real-world example, the Managed DirectX billboard sample used to run at ~30% of the speed of the C++ version; where all the other samples were running at ~90%. The reason for this was that the billboards were being sorted using the default comparer (and thus being boxed), as it turns out 4MB of data was being copied around every frame thanks to this.

How does it work?

Dictionary<K,V> will provide EqualityComparer<T>.Default to itself via the default constructor. What the default equality comparer does is (basically, notice how much boxing occurs):

It is possible to eliminate the boxing overhead by implementing an interface on a struct (such as IEquatable<T>). However, there are many surprising rules for when boxing occurs under these circumstances so I would recommend using the paired interface (e.g. IEqualityComparer<T> in this case) if at all possible.

Email codedump link for Efficiency of using IEqualityComparer in Dictionary vs HashCode and Equals()