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