31

How accurate is System.Diagnostics.Stopwatch? I am trying to do some metrics for different code paths and I need it to be exact. Should I be using stopwatch or is there another solution that is more accurate.

I have been told that sometimes stopwatch gives incorrect information.

Daniel Daranas
  • 22,454
  • 9
  • 63
  • 116
leora
  • 188,729
  • 360
  • 878
  • 1,366
  • Thanks for the question. I didn't even know there was such a class in the framework until now. Heh. – Ishmaeel Jan 28 '09 at 12:02
  • 6
    I've written an article about that. It shows how you get good measurements out of the stopwatch class: http://www.codeproject.com/KB/testing/stopwatch-measure-precise.aspx – Thomas Maierhofer Mar 04 '10 at 12:33
  • 1
    Is millisecond accuracy enough? Should be sufficient for your purposes. Define "accurate". – duffymo Dec 26 '08 at 17:29
  • i know it can give you milliseconds but i have been told that there are many cases where its not accurate – leora Dec 26 '08 at 17:31
  • 3
    BTW, since this is a very old question now, in newer .NETs running on newer hardware, stopwatch accuracy is much better, because (as Lee Grisholm says in a comment on Kernelman's answer), it is now a wrapper around QueryPerformanceCounter. – ToolmakerSteve Sep 23 '15 at 09:42
  • Don't ever rely on a single measurement of **anything** for accuracy. Run each code path for several minutes and count the number of iterations to get an average. – HUAGHAGUAH Dec 26 '08 at 17:33

8 Answers8

22

I've just written an article that explains how a test setup must be done to get an high accuracy (better than 0.1ms) out of the stopwatch. I Think it should explain everything.

http://www.codeproject.com/KB/testing/stopwatch-measure-precise.aspx

tomfanning
  • 9,552
  • 4
  • 50
  • 78
Thomas Maierhofer
  • 2,665
  • 18
  • 33
  • 2
    Seconds is a lower case s. ms not mS. http://en.wikipedia.org/wiki/Second#SI_multiples (same in your article) – Jannes Feb 10 '12 at 22:47
  • Your article somewhat contradicts to what MS states here: https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396#Guidance MSDN. They claim that for most hardware, Stopwatch() is fastest and accurate especially for multiprocessor CPUs and frequence-changing-CPUs (which are most modern CPUs I would guess). Do you still think, it is worth, to run time-manamgent on only one thread (if possible)? – Philm May 03 '17 at 20:31
7

The System.Diagnostics.Stopwatch class does accurately measure time elapsed, but the way that the ElapsedTicks method works has led some people to the conclusion that it is not accurate, when they really just have a logic error in their code.

The reason that some developers think that the Stopwatch is not accurate is that the ElapsedTicks from the Stopwatch DO NOT EQUATE to the Ticks in a DateTime. The problem arises when the application code uses the ElapsedTicks to create a new DateTime.

var watch = new Stopwatch();
watch.Start();
... (perform a set of operations)
watch.Stop();
var wrongDate = new DateTime(watch.ElapsedTicks); // This is the WRONG value.

If necessary, the stopwatch duration can be converted to a DateTime in the following way:

// This converts stopwatch ticks into DateTime ticks.
// First convert to TimeSpan, then convert to DateTime
var rightDate = new DateTime(watch.Elapsed.Ticks); 

Here is an article that explains the problem in more detail: http://geekswithblogs.net/BlackRabbitCoder/archive/2012/01/12/c.net-little-pitfalls-stopwatch-ticks-are-not-timespan-ticks.aspx

Note that the content is no longer available at the original link. Here is a reference to the archived content from the Wayback Machine: https://web.archive.org/web/20190104073827/http://geekswithblogs.net:80/BlackRabbitCoder/archive/2012/01/12/c.net-little-pitfalls-stopwatch-ticks-are-not-timespan-ticks.aspx

user3308241
  • 344
  • 3
  • 10
2

Stopwatch class return different values under different configuration as Frequency depends on the installed hardware & operating system.

Using stopwatch class we can have only the rough estimation of execution time. And for each execution it returns different value so we have to take average of different execution.

More Info : http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx

Aditya Acharya
  • 375
  • 4
  • 11
2

First, exact is of course not a possible or meaningful concept when talking about time or space, since no empyrical measurement of a physical magnitude can ever pretend to be exact.

Second, David Bolton's blog article may be useful. I'm quoting:

If this was timed with the high resolution counter then it will be accurate to microseconds. It is actually accurate to nanoseconds (10-9 seconds, ie a billionth of a second) but there is so much other stuff going on that nanosecond accuracy is really a bit pointless. When doing timing or benchmarking of code, you should do a number of runs and take the average time- because of other processes running under Windows, how much swapping to disk is occurring etc, the values between two runs may vary.

Daniel Daranas
  • 22,454
  • 9
  • 63
  • 116
  • 2
    The main problem is not disk I/O it is in fact thread context switches. With the newer versions of the .NET framework and Windows this problem has become less important, but it is still there. – Thomas Maierhofer Sep 15 '14 at 09:31
1

MSDN has some examples of the stopwatch. They also have it showing how accurate it is within Nanoseconds. Hope this helps!

Jab
  • 13,713
  • 2
  • 42
  • 48
  • 1
    I ran their sample code. It said it would be accurate to within 0 nanoseconds, and gave me a result of -657ms for one of the tests. Not very helpful! – D'Arcy Rittich Dec 26 '08 at 17:43
  • 2
    Precision and Accuracy are not the same thing. Your computer does not have nanosecond accuracy. It doesn't even have millisecond accuracy. – mmcdole Dec 26 '08 at 18:45
  • 1
    Yes it does. Not always, but recent computers use the RDTSC CPU instruction. It can be accurate up to the frequency of the CPU (like 3 GHz). However, I'm having issues with some newer hardware where the StopWatch.Frequency is around 2MHz (so I'm guessing Windows is using some other clock on the motherboard), but for some reason that frequency is not very stable, leading to error into the milliseconds... which is why I'm browsing stackoverflow for it. – Jannes Feb 10 '12 at 22:46
0

In addition to seconding the advice of HUAGHAGUAH above, I'd add that you should be VERY skeptical of micro-benchmarks in general. While close-focused performance testing has a legitimate place, it's very easy to tweak an unimportant detail. So write and verify code that is designed for readability and clarity, then profile it to find out where the hot spots are (or whether there are any worth worrying about), and then tune (only) those portions.

I recall working with a programmer who micro-optimized a bit of code that executed while the system waited for human input. The time savings absolutely disappeared in the between-keystroke lag!

joel.neely
  • 30,725
  • 9
  • 56
  • 64
0

Why you don't profile your code instead of focusing on micro-benchmarks?

There are some good Open Source profilers like:

Jafin
  • 4,153
  • 1
  • 40
  • 52
Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
  • 2
    Note that the NProf site at Google Code says NProf is no longer under development -- it recommends [SlimTune](http://code.google.com/p/slimtune/) instead. – Jonathan Leffler Apr 05 '11 at 05:11
  • 11
    Useful information, but this is an answer for a different question. – A.R. Apr 15 '15 at 21:12
  • 8
    This does not answer the question, as stated. – Adam White Dec 10 '16 at 14:13
  • 1
    Answer to comments as "..does not answer the question" : On the contrary. This answers the question, if you read it: "Should I be using stopwatch or is there another solution that is more accurate". It only doesn't answer the headline of the question. Besides that, there are people here (as me) who see **improvement suggestions** as important and welcome answers, and for me this includes also references to alternative solutions. I have some problems to understand, why there seem to be not few people around here, who need to critisize that (?) – Philm May 03 '17 at 10:33
  • @Philm: Agreed, but it's unfortunate that this is the top Google result for "C# stopwatch resolution" – Ed S. May 17 '19 at 20:14
0

If you want more precise timings. Take a look at the QueryPerformanceCounter. MSDN link for QueryPerformanceCounter. A neat implementation is given here. The example loads coredll.dll for CE, for Windows you should load the Kernel32.dll as stated in the MSDN documentation.

kernelman
  • 41
  • 2
  • 15
  • 9
    Looking at the source code for Stopwatch class (using .NET Reflector), it's already a very thin wrapper around QueryPerformanceCounter. – Lee Grissom Jan 24 '12 at 20:23