These are just fine for timing webservices, round-trips to the database and even measuring the overall performance of your system from a use-case perspective (UI click to results back). But for really accurate timings you need to use system ticks, i.e. ticks of the high-resolution timer: System.Diagnostics.Stopwatch.GetTimestamp()[1]. This timer’s frequency (and hence resolution) depends on your system. On mine:

System.Diagnostics.Stopwatch.Frequency = 3,325,040,000 ticks/sec

…which I make to be 0.3ns ticks. So some 300x more accurate than DateTime.Now, and accurate enough to start measuring fine-grained performance costs, like boxing/unboxing vs generic lists.

Clearly it’s overkill to use that level of precision in many cases, but if you’re logging to system performance counters you must use those ‘kind of ticks’, because that’s what counter types like PerformanceCounterType.AverageTimer and PerformanceCounterType.CounterTimer require.

[1] Thankfully since .Net 2, we don’t have to use P/Invoke to access this functionality anymore. On one occasion I mistyped the interop signature (to return void), and created a web-app that ran fine as a debug build, but failed spectacularly when built for release. Took a while to track that one down...

All these are idle timings, however I didn't think that the stopwatch frequency was affected by CPU clock-rate shifting technologies. Otherwise a stopwatch timing that spanned over a idle/busy period would report completely the wrong duration.