So I’m a bit behind on my blog reading and I came across this post by Keyvan Nayyeri via The Morning Brew. In it, he goes on to compare the performance of DateTime.Now versus DateTime.UtcNow.

Now, to be fair, I did not know that DateTime.Now was that much more expensive then Date.UtcNow. I mean, hey, how expensive could it be to add an extra hour to the time value, right? Colour me surprised when according to this post it’s 117 times slower. Reading Keyvan’s post, I came across this line:

Most of the developers are careless about all the properties and methods provided by built-in types in a language, so they don’t discover all the details about them. In fact, they use something that just solves their problem regardless of the side-effects.

True, I have been ‘carelessly’ using the DateTime.Now property not fully knowing the performance characteristics. So I decided to examine how much cost we’re talking about. I downloaded the sample code and ran it on my system. Here’s some of the output:

Testing DateTime.Now …

Sample Size: 5000 – Time: 308607

Testing DateTime.UtcNow …

Sample Size: 5000 – Time: 6753

That is a big difference but what do those bold numbers mean? Those numbers actually come from QueryPerformanceCounter, a Win32 API call that returns values from a high-resolution timer. To calculate the time difference, you need to divide that value from the result of QueryPerformanceFrequency, another Win32 call.

On my machine, that means that the duration of 5000 calls to DateTime.Now and DateTime.UtcNow are 21.55ms and 0.47ms respectively. So on a per call basis we’re looking at a difference of 4.22μs. For those of you who don’t know, μs represents microseconds. Now let’s go back and look at the original Twitter exchange that was the impetus for the post:

“I’m looking through a method right now where someone had used DateTime.Now 15 times. In one method.”

Now my point is this: In programming, abstraction is not a bug, it’s a feature. Whether it’s the idiosyncrasies of the Windows API, hidden behind the .NET framework or all your data stored in AWS. Some of them you can use Reflector to look at how they’re implemented and some of them are trade secrets. What’s for sure is that you will never know the underlying implementations of them all.

Now I’m not arguing for ignorance. Please do understand your tools and technologies. But when it comes to performance, there are only 2 rules:

Rule #1: Measure
Rule #2: Do Your Homework

These rules have served me well over the years because it’s impossible to predict where your bottlenecks will come from. Use profilers to draw you to the problem areas of your code and not the minutiae.

Shaving off a few microseconds with DateTime won’t be half as useful as removing that extra web service call you didn’t know you were making.