-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
@vancem commented on Tue Sep 05 2017
I thought we fixed this but I just checked and we have not, so I am logging an issue.
DateTime.Now is over 10X SLOWER than DateTime.UtcNow.
I ran the the trivial program below
var start = DateTime.Now;
while ((DateTime.Now-start).TotalSeconds < 5)
{
}while profiling with PerfView to get the following data
| Name | Inc % | Inc |
|---|---|---|
| || |+ system.private.corelib!System.DateTime.get_Now() | 95.4 | 4,832 |
| || | + system.private.corelib!TimeZoneInfo.GetDateTimeNowUtcOffsetFromUtc | 88.1 | 4,462 |
| || | + system.private.corelib!System.DateTime.get_UtcNow() | 5.8 | 293 |
which show that only 6% of time is spent actually fetching the time, and 95% of the time was figuring out what time zone we are in.
This mapping from Utc time to local time could be cached and all the inefficiency removed.
This is important because people DO use DateTIme.Now to measure the durations of fast things (in fact we improved DateTime.UtcNow so that it has a accuracy of < 1msec). Currently we tell people to avoid DateTime.Now (use DateTime.UtcNow), to avoid this inefficiency, but we could easily make DateTIme.Now almost the same cost
This is only a small amount of work, we should just do it.
@danmosemsft , @karelz
@mikedn commented on Tue Sep 05 2017
Currently we tell people to avoid DateTime.Now (use DateTime.UtcNow), to avoid this inefficiency
I don't know about others but I avoid DateTime.Now not because it's inefficient but because it is plain wrong to use it to measure durations. Or more generally, to use it for anything that doesn't involve displaying the local time to the user...
Let's keep DateTime.Now slow to encourage devs to do the right thing 😁
@karelz commented on Tue Sep 05 2017
Marking as up-for-grabs.
Moderate cost (as it requires perf measurements before and after the change)
@danmosemsft commented on Tue Sep 05 2017
mapping from Utc time to local time could be cached
Of course, daylight savings could begin one second from now so it presumably can't be trivially cached. @tarekgh is there a way that DateTime can be told when the local time offset changes, instead of asking each call? I'm sure there has been thinking about this in the past.
@tarekgh commented on Tue Sep 05 2017
is there a way that DateTime can be told when the local time offset changes
No, we don't have a way to know that. We looked before, and the way you can know that (on Windows) is either you have a Window and listen to some window message or you use WinRT API. Obviously, both are not a good solution for us.
Also, it is difficult to know if we are passing the daylight saving at any moment to know we need to adjust the calculation (or the cache).
We already have some optimization here:
http://source.dot.net/#System.Private.CoreLib/src/System/TimeZoneInfo.Win32.cs,50
but we still doing the calculations here:
http://source.dot.net/#System.Private.CoreLib/src/System/TimeZoneInfo.Win32.cs,402
because of we cannot know if we crossed the daylight or not.
by the way, the optimization we have there has a bug. that can tell when trying to optimize, you can run into some other problems.
@vancem commented on Tue Sep 05 2017
On the caching issue: It seems to me that when you calculate daylight savings time, you can also know when it will change (at worst you probe say 4 hours into the future and see if it is different, since you know that daylight savings time only happens 2 a year, if you get the same number for now and 4 hours from now, you can know that for the next 4 hours it will not change). The next time you want Now you can then just check if the time is in the 'known' region and if so use the cached DST value.
@mikedn - yes, arguably DateTime.Now is bad for computing deltas (since any time you cross DST, you get a weird value). However giving bad perf does not actually change behavior, it just makes their code that much worse. There are also correct usages (when you just want a timestamp). The bottom line is that if people use it at all frequently (and we have evidence that they do), it is worth optimizing.
@tarekgh commented on Tue Sep 05 2017
@vancem yes, in general, I agree there is a way we can optimize. we just want to be careful to not affect the functionality and not have a complex solution.
To mention, instead of probing for some time (4 hours in your example) we can just calculate the exact time we are going to switch the daylight when we create the cache. and then we always check against this time to know if we need to update the cache or just use the cached offset.
@danmosemsft commented on Tue Sep 05 2017
If the machine time zone changes, do we need to listen to that?
@tarekgh commented on Tue Sep 05 2017
If the machine time zone changes, do we need to listen to that?
Same answer:
No, we don't have a way to know that. We looked before, and the way you can know that (on Windows) is either you have a Window and listen to some window message or you use WinRT API. Obviously, both are not a good solution for us.
Today we ask the apps to listen to the TZ changes on the machine and then call us to clear the cache.
@danmosemsft commented on Wed Nov 29 2017
Moving to CoreFX to track more easily.