March 9, 2009
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:
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
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 at March 9, 2009 8:25 AM
TrackBack URL for this entry: