Stopwatch vs. using System.DateTime.Now for timing events

68,855

Solution 1

As per MSDN:

The Stopwatch measures elapsed time by counting timer ticks in the underlying timer mechanism. If the installed hardware and operating system support a high-resolution performance counter, then the Stopwatch class uses that counter to measure elapsed time. Otherwise, the Stopwatch class uses the system timer to measure elapsed time. Use the Frequency and IsHighResolution fields to determine the precision and resolution of the Stopwatch timing implementation.

It uses a higher resolution / precision than DateTime.Now.

You can also check out these related links:

Environment.TickCount vs DateTime.Now

Is DateTime.Now the best way to measure a function's performance?

DateTime is good enough for precision to the second probably but anything beyond that I would recommend StopWatch.

Solution 2

It's better to use the Stopwatch class because it's much more accurate than subtracting DateTime values:

Stopwatch s = Stopwatch.StartNew();
// Tested code here
s.Stop();
Console.WriteLine("Elapsed Time: {0} ms", s.ElapsedMilliseconds);

Unfortunately, this simple piece of code won't be enough to get accurate measurements most of the times because there’s a lot of activity going on under the hood of the OS, which can steal some CPU time and slow down the execution of your code. That’s why it is best to execute the tests multiple times and then remove the lowest and the highest times. For that puprose it is a good solution to have a method that executes the tested code multiple times, removes the lowest and the greatest times and calculates the average time. I have published a sample testing method in my blog.

Solution 3

this timing function performance link discusses your exact problem, specifically this paragraph:

The problem is that according to MSDN the resolution of the DateTime.Now function is 10+ milliseconds, and we need to call it twice! So that would introduce a 20+ ms swing in your runtime measurement. As our function calls are often likely to be a lot quicker to return than this 20ms window this isn’t good enough.

EDIT: It kind of sounds like the second DateTime.Now is being called at a different time than when the stopwatch method concludes.

Share:
68,855

Related videos on Youtube

Randy Minder
Author by

Randy Minder

Azure Data Architect / Business Intelligence / Tabular Modeling / Power BI Significant experience with data architecture (database architecture, data warehouses, data marts), SSIS and Azure Data Factory, Business Intelligence with Power BI. Check out my new course on Udemy titled "The DAX Workshop Part 1". The best way to learn DAX is by working through real-world scenarios. The course is filled with exercises (45) to help you learn how to use DAX. Our careers and hobbies are fun and important. But each of us has a soul which will live forever, after our bodies die. Do you know where you'll spend eternity? Jesus Christ said there is only one way to heaven, and it is through Him. You won't get a second chance after you die.

Updated on December 21, 2020

Comments

  • Randy Minder
    Randy Minder over 3 years

    I wanted to track the performance of my code so I stored the start and end time using System.DateTime.Now. I took the difference between the two as the time my code to execute.

    I noticed though that the difference didn't appear to be accurate. So I tried using a Stopwatch object. This turned out to be much, much more accurate.

    Can anyone tell me why Stopwatch would be more accurate than calculating the difference between a start and end time using System.DateTime.Now?

    BTW, I'm not talking about a tenths of a percent. I get about a 15-20% difference.

    • Igby Largeman
      Igby Largeman about 14 years
      Based on your comment to Kelsey's answer, I'd be interested in seeing the code that records the start and stop times. A difference of 11 seconds (huge) is nothing to do with the accuracy differences of the two classes, so something else has to be going on.
    • Daniel Pryden
      Daniel Pryden about 14 years
      Also, if you're only interested in the TimeSpan between two dates, it's usually better to use DateTime.UtcNow instead of DateTime.Now, since you usually don't want daylight time shifts and other local time variations to influence the result.
    • Matt Johnson-Pint
      Matt Johnson-Pint over 10 years
      @DanielPryden, See The Case Against DateTime.Now, which makes that point exactly. +1
  • displayName
    displayName almost 9 years
    I checked your blog's link. There is a slight error in the calculation of the average timing. Instead of double averageTime = ((double)totalTime) / (count - discardCount); it should be double averageTime = ((double)totalTime) / (count - (2*discardCount));. No?
  • Pavel Vladov
    Pavel Vladov almost 9 years
    Hi, no it shouldn't, the code in the blog is correct. Please take a look at the line, where count is defined. It is defined as: int count = repetitions - discardCount;. That is why when calculating the average time I subtract discardCount only once (it has already been subtracted once). Regards.
  • displayName
    displayName almost 9 years
    That's correct. Didn't pay attention to it. You are right.
  • mirhagk
    mirhagk over 7 years
    It's worth mentioning that another way to measure time is to just pick the top X of N runs. Like run it 5 times and use the best one. This is the one that will have the least OS interference after all. There's pros and cons to both approaches however
  • Ünsal Ersöz
    Ünsal Ersöz almost 5 years
    Here: blogs.msdn.microsoft.com/ericlippert/2010/04/08/… ; Eric Lippert has a nice explanation about how much precission it has. 1/64 of a second at best. Two calls one at the beginning and at the end, then you have 1/32 of a second as precission, which might be up to ~31 ms sway.