Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Environment.TickCount vs DateTime.Now

Is it ever OK to use Environment.TickCountto calculate time spans?

int start = Environment.TickCount; // Do stuff int duration = Environment.TickCount - start; Console.WriteLine("That took " + duration " ms"); 

Because TickCount is signed and will rollover after 25 days (it takes 50 days to hit all 32 bits, but you have to scrap the signed bit if you want to make any sense of the math), it seems like it's too risky to be useful.

I'm using DateTime.Now instead. Is this the best way to do this?

DateTime start = DateTime.Now; // Do stuff TimeSpan duration = DateTime.Now - start; Console.WriteLine("That took " + duration.TotalMilliseconds + " ms"); 
like image 374
Jon B Avatar asked Oct 28 '08 13:10

Jon B


People also ask

What is environment TickCount?

The TickCount property cycles between Int32. MinValue, which is a negative number, and Int32. MaxValue once every 49.8 days. This code sample removes the sign bit to yield a nonnegative number that cycles between zero and MaxValue once every 24.9 days.

What is Tick count?

Tick Counter is a feature available for charts using Tick aggregation. This feature shows dynamic tick information for the last bar on chart, which includes the number of ticks since the open and the number of ticks until completion.


1 Answers

Environment.TickCount is based on GetTickCount() WinAPI function. It's in milliseconds But the actual precision of it is about 15.6 ms. So you can't measure shorter time intervals (or you'll get 0)

Note: The returned value is Int32, so this counter rolls over each ~49.7 days. You shouldn't use it to measure such long intervals.

DateTime.Ticks is based on GetSystemTimeAsFileTime() WinAPI function. It's in 100s nanoseconds (tenths of microsoconds). The actual precision of DateTime.Ticks depends on the system. On XP, the increment of system clock is about 15.6 ms, the same as in Environment.TickCount. On Windows 7 its precision is 1 ms (while Environemnt.TickCount's is still 15.6 ms), however if a power saving scheme is used (usually on laptops) it can go down to 15.6 ms as well.

Stopwatch is based on QueryPerformanceCounter() WinAPI function (but if high-resolution performance counter is not supported by your system, DateTime.Ticks is used)

Before using StopWatch notice two problems:

  • it can be unreliable on multiprocessor systems (see MS kb895980, kb896256)
  • it can be unreliable if CPU frequency varies (read this article)

You can evaluate the precision on your system with simple test:

static void Main(string[] args) {     int xcnt = 0;     long xdelta, xstart;     xstart = DateTime.UtcNow.Ticks;     do {         xdelta = DateTime.UtcNow.Ticks - xstart;         xcnt++;     } while (xdelta == 0);      Console.WriteLine("DateTime:\t{0} ms, in {1} cycles", xdelta / (10000.0), xcnt);      int ycnt = 0, ystart;     long ydelta;     ystart = Environment.TickCount;     do {         ydelta = Environment.TickCount - ystart;         ycnt++;     } while (ydelta == 0);      Console.WriteLine("Environment:\t{0} ms, in {1} cycles ", ydelta, ycnt);       Stopwatch sw = new Stopwatch();     int zcnt = 0;     long zstart, zdelta;      sw.Start();     zstart = sw.ElapsedTicks; // This minimizes the difference (opposed to just using 0)     do {         zdelta = sw.ElapsedTicks - zstart;         zcnt++;     } while (zdelta == 0);     sw.Stop();      Console.WriteLine("StopWatch:\t{0} ms, in {1} cycles", (zdelta * 1000.0) / Stopwatch.Frequency, zcnt);     Console.ReadKey(); } 
like image 81
mistika Avatar answered Sep 20 '22 09:09

mistika