Unity’s Time class is an easy way to get the relative time. You can find the time since the app started with Time.time or the time between frames with Time.deltaTime. But what if you want to know the absolute time? You may need to display a clock to the user, send a timestamp over a network, or record when a game was saved. This is where System.DateTime comes in. It’s powerful and offers so much functionality that it’s natural to worry about about how slow it’ll be. So today’s article puts it to the test to find out how much time is being spent in operations like DateTime.Now which gets the current date and time. Is it quick enough that you shouldn’t worry? Read on to find out.

The docs for DateTime tell us that it has tons of features. Most programmers stick to a few core functions and that’s what I’ll be testing today.

The first is the static Now property that returns you a DateTime representing the current date and time. This has some great advantages over Time.time. First, it’s not just a snapshot of the time at the start of the frame. It’s actually up to date as of the exact time you call Now. It also returns you a full DateTime, meaning you get the absolute date and time, including milliseconds.

Second is the AddSeconds function, one of the many AddX functions for advancing the DateTime by some amount of time. One common use for these is to transform an offset into an actual DateTime. For example, if you have a UNIX timestamp it is the number of seconds since January 1, 1970. You can make a DateTime for that date and then call AddSeconds on it to get the actual date.

Third is the reverse of the AddX functions: subtracting two DateTime objects to get a TimeSpan. This represents the amount of time between them, and it easily queried to see how long that is in seconds, days, and so forth. Given that calendars are really complex and include things like leap years, this is a really easy way to check how much time has really elapsed between two DateTime instances.

Lastly, DateTime has an overloaded ToString that allows you to easily format it into whatever kind of string you’d like. You might want July 20, 2015 to be “07-20-2015”, “20-07-2015”, or “July 20, 2015”. Check out the docs for a full formatting guide.

Now let’s take a look at the test:

using System;
using System.Collections;
using System.Collections.Generic;
 
using UnityEngine;
 
public class TestScript : MonoBehaviour
{
	private const int NumIterations = 1000000;
 
	private string report;
 
	void Start()
	{
		var stopwatch = new System.Diagnostics.Stopwatch();
		DateTime dt = DateTime.Now;
 
		stopwatch.Reset();
		stopwatch.Start();
		for (var i = 0; i < NumIterations; ++i)
		{
			dt = DateTime.Now;
		}
		var nowTime = stopwatch.ElapsedMilliseconds;
 
		stopwatch.Reset();
		stopwatch.Start();
		for (var i = 0; i < NumIterations; ++i)
		{
			dt = dt.AddSeconds(123);
		}
		var addSecondsTime = stopwatch.ElapsedMilliseconds;
 
		var epochStart = new DateTime(1970, 1, 1);
		stopwatch.Reset();
		stopwatch.Start();
		for (var i = 0; i < NumIterations; ++i)
		{
			var timeSpan = dt - epochStart;
		}
		var subtractTime = stopwatch.ElapsedMilliseconds;
 
		stopwatch.Reset();
		stopwatch.Start();
		for (var i = 0; i < NumIterations; ++i)
		{
			dt.ToString("dddd, MMMM d, yyyy");
		}
		var toStringTime = stopwatch.ElapsedMilliseconds;
 
		report = "Operation,Time\n"
			+ "DateTime.Now," + nowTime + "\n"
			+ "DateTime.AddSeconds," + addSecondsTime + "\n"
			+ "DateTime-DateTime," + subtractTime + "\n"
			+ "DateTime.ToString," + toStringTime;
	}
 
	void OnGUI()
	{
		GUI.TextArea(new Rect(0, 0, Screen.width, Screen.height), report);
	}
}

If you want to try out the test yourself, simply paste the above code into a TestScript.cs file in your Unity project’s Assets directory and attach it to the main camera game object in a new, empty project. Then build in non-development mode for 64-bit processors and run it windowed at 640×480 with fastest graphics. I ran it that way on this machine:

  • 2.3 Ghz Intel Core i7-3615QM
  • Mac OS X 10.10.4
  • Unity 5.1.2f1, Mac OS X Standalone, x86_64, non-development
  • 640×480, Fastest, Windowed

And here are the results I got:

Operation Time
DateTime.Now 86
DateTime.AddSeconds 41
DateTime-DateTime 13
DateTime.ToString 1652

DateTime Performance

DateTime Performance (Fast Operations Only)

There are some pretty big speed differences between these functions, but they’re not really meant to be compared apples-to-apples. They’re unique operations, not alternatives for each other. What’s more important is their individual performance in an absolute sense.

To examine that, let’s consider that each operation was run one million times. This means that the slowest operation by far, ToString took about 0.001652 milliseconds. That’s really not much time, even if it took much longer on a slower CPU. The other operations take one twentieth of that time, which is pretty much negligible.

The takeaway is that as long as you’re not performing thousands of DateTime operations per frame, you’ll probably be just fine. It’s a pretty quick API, so go ahead and use it when you need absolute times.

Have you had any interesting come up when using DateTime? Let me know in the comments!