Comparison of Environment.TickCount, DateTime.Now.Ticks and Stopwatch.ElapsedMilliseconds

By | 2015.08.17

Doing game development I use a lot of timers. Every Update() I check if its time to do something. To make this as light as possible I made a small benchmark to check the speed of different ways of getting time.

When running the code ignore the first 1000-result from each test (used for warmup). Also ignore the number printed after “ignore:”, its just there just to ensure no compiler optimization is done that would affect the result.

Results on my computer:

Test1 1000000: 7ms    - Environment.TickCount
Test2 1000000: 1392ms - DateTime.Now.Ticks
Test3 1000000: 933ms  - Stopwatch.ElapsedMilliseconds

Both DateTime.Now.Ticks (test 2) and Stopwatch.ElapsedMilliseconds (test 3) are considerably slower than Environment.TickCount (test 1), but not enough to be noticeable unless you are performing a lot of calculations. For example I was investigating this because I need a cheap way of getting time in tight game loops. The thing to note is that Environment.TickCount is 32-bit signed which means that after 2147483 seconds of uptime (24,85513 days) the counter overflows and goes to –2147483648 (minus 24,85513 days).

Tip! You can force an overflow to 0 after a max value of 49 days by converting it to an unsigned integer: var value = unchecked((UInt32)Environment.TickCount)

Benchmark code:

static void Main(string[] args)
{
    Test1(1000);
    Test1(1000000);
    Test2(1000);
    Test2(1000000);
    Test3(1000);
    Test3(1000000);

    Console.ReadLine();
}

      

static void Test1(int c)
{
    var sw = new Stopwatch();
    sw.Start();
    long sum = 0;
    for (var i = 0; i < c; i++)
    {
        sum += Environment.TickCount;
    }
    sw.Stop();
    Console.WriteLine("Test1 " + c + ": " + sw.ElapsedMilliseconds + "   (ignore: " + sum + ")");
}

static void Test2(int c)
{
    var sw = new Stopwatch();
    sw.Start();
    long sum = 0;
    for (var i = 0; i < c; i++)
    {
        sum += DateTime.Now.Ticks;
    }
    sw.Stop();
    Console.WriteLine("Test2 " + c + ": " + sw.ElapsedMilliseconds + "   (ignore: " + sum + ")");
}
static void Test3(int c)
{
    var sw = new Stopwatch();
    sw.Start();
    long sum = 0;
    var stopwatch = new Stopwatch();
    stopwatch.Start();
    for (var i = 0; i < c; i++)
    {
        sum += stopwatch.ElapsedMilliseconds;
    }
    sw.Stop();
    Console.WriteLine("Test3 " + c + ": " + sw.ElapsedMilliseconds + "   (ignore: " + sum + ")");
}

 

Leave a Reply