Subtle Differences

What’s the difference between the values generated by the following statements?

long ticks1 = stopwatch.ElapsedTicks;
long ticks2 = stopwatch.Elapsed.Ticks;

While the latter uses the standard 100-nanosecond intervals (used by FILETIME, DateTime, etc.) as its units, the former reports the number of ticks as measured by the system’s high-resolution performance counter, and is not very meaningful until divided by Stopwatch.Frequency. The use of the noun ‘ticks’ to describe both is unfortunate.

Here’s another difference, which turns out to not be so significant after all:

using System.Linq;
// ...
bool contains1 = dictionary.ContainsKey(value);
bool contains2 = dictionary.Keys.Contains(value);

I initially assumed that the second statement—which invokes the Enumerable.Contains extension method—would perform a linear search over a copy of all the keys in the Dictionary. However, some exploration with Reflector showed that Enumerable.Contains first checks if its parameter implements ICollection<T>. The KeyCollection returned by Dictionary<K, V>.Keys does implement this interface, and its implementation of Contains simply delegates to ContainsKey. Experimentation showed that the latter statement only takes twice as long as the first—not the O(1) vs O(n) difference I was expecting. While API duplication should be avoided, some overlap is inevitable when retrofitting extension methods to an existing codebase; it’s very nice that the LINQ to Objects design allows for an efficient implementation to be chosen when it’s available.

Posted by Bradley Grainger on March 09, 2009