A colleague and I are going back and forth on this issue and I'm hoping to get some outside opinions as to whether or not my proposed solution is a good idea.
First, a disclaimer: I realize that the notion of "optimizing DateTime.Now
" sounds crazy to some of you. I have a couple of pre-emptive defenses:
- I sometimes suspect that those people who always say, "Computers are fast; readability always comes before optimization" are often speaking from experience developing applications where performance, though it may be important, is not critical. I'm talking about needing things to happen as close to instantaneously as possible -- like, within nanoseconds (in certain industries, this does matter -- for instance, real-time high-frequency trading).
- Even with that in mind, the alternative approach I describe below is, in fact, quite readable. It is not a bizarre hack, just a simple method that works reliably and fast.
- We have runs tests.
DateTime.Now
is slow (relatively speaking). The method below is faster.
Now, onto the question itself.
Basically, from tests, we've found that DateTime.Now
takes roughly 25 ticks (around 2.5 microseconds) to run. This is averaged out over thousands to millions of calls, of course. It appears that the first call actually takes a significant amount of time and subsequent calls are much faster. But still, 25 ticks is the average.
However, my colleague and I noticed that DateTime.UtcNow
takes substantially less time to run -- on average, a mere 0.03 microseconds.
Given that our application will never be running while there is a change in Daylight Savings Time, my suggestion was to create the following class:
public static class FastDateTime {
public static TimeSpan LocalUtcOffset { get; private set; }
public static DateTime Now {
get { return DateTime.UtcNow + LocalUtcOffset; }
}
static FastDateTime() {
LocalUtcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
}
}
In other words, determine the UTC offset for the local timezone once -- at startup -- and from that point onward leverage the speed of DateTime.UtcNow
to get the current time a lot faster via FastDateTime.Now
.
I could see this being a problem if the UTC offset changed during the time the application was running (if, for example, the application was running overnight); but as I stated already, in our case, that will not happen.
My colleague has a different idea about how to do it, which is a bit too involved for me to explain here. Ultimately, as far as I can tell, both of our approaches return an accurate result, mine being slightly faster (~0.07 microseconds vs. ~0.21 microseconds).
What I want to know is:
- Am I missing something here? Given the abovementioned fact that the application will only run within the time frame of a single date, is
FastDateTime.Now
safe? - Can anyone else perhaps think of an even faster way of getting the current time?