[英]Optimizing alternatives to DateTime.Now
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. 首先,免责声明:我意识到“优化
DateTime.Now
”的概念对你们中的某些人来说听起来很疯狂。 I have a couple of pre-emptive defenses: 我有几个先发制人的防御措施:
DateTime.Now
is slow (relatively speaking). DateTime.Now
很慢(相对而言)。 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. 基本上,通过测试,我们发现
DateTime.Now
大约需要25个刻度(大约2.5微秒)才能运行。 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.
但仍然是25个蜱是平均值。
However, my colleague and I noticed that DateTime.UtcNow
takes substantially less time to run -- on average, a mere 0.03 microseconds. 然而,我的同事和我注意到
DateTime.UtcNow
运行的时间要少得多 - 平均只有0.03微秒。
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
. 换句话说,确定UTC本地时区偏移一次 -在启动-并从该点开始利用速度
DateTime.UtcNow
通过获取当前的时间快了很多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); 如果在应用程序运行期间UTC偏移发生了变化(例如,如果应用程序在一夜之间运行),我可以看到这是一个问题; 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).
最终, 据我所知 ,我们的两种方法都返回了准确的结果,我的方法稍快一些(约0.07微秒与~0.21微秒)。
What I want to know is: 我想知道的是:
FastDateTime.Now
safe? FastDateTime.Now
安全? Could you just use DateTime.UtcNow, and only convert to local time when the data is presented? 你能使用DateTime.UtcNow,只在数据出现时转换为本地时间吗? You've already determined that DateTime.UtcNow is much faster and it will remove any ambiguity around DST.
您已经确定DateTime.UtcNow更快,它将消除DST周围的任何歧义。
One difference between the result of 结果之一的一个区别
DateTime.Now
and 和
DateTime.UtcNow + LocalUtcOffset
is the value of the Kind property - Local vs Utc respectively. 是Kind属性的值 - Local vs Utc。 If the resultant DateTime is being passed to a third party library consider returning
如果将生成的DateTime传递给第三方库,请考虑返回
DateTime.SpecifyKind(DateTime.UtcNow + LocalUtcOffset, DateTimeKind.Local)
I like your solution. 我喜欢你的解决方案。 I made some tests to see how much faster it is compared to regular
DateTime.Now
我做了一些测试,看看它与常规
DateTime.Now
相比有多快
DateTime.UtcNow
is 117 times faster than DateTime.Now
DateTime.UtcNow
比DateTime.Now
快117倍
using DateTime.UtcNow
is good enough if we are only interested in the duration and not the time itself. 如果我们只关注持续时间而不是时间本身,那么使用
DateTime.UtcNow
就足够了。 If all we need is to calculate the duration of a specific code section ( doing duration= End_time - Start_time
) then the time zone is not important and DateTime.UtcNow
is sufficient. 如果我们只需要计算特定代码段的
duration= End_time - Start_time
(执行duration= End_time - Start_time
),那么时区并不重要,而DateTime.UtcNow
就足够了。
But if we need the time itself then we need to do DateTime.UtcNow + LocalUtcOffset
但是如果我们需要时间本身,那么我们需要做
DateTime.UtcNow + LocalUtcOffset
Just adding the time span slows down a little bit and now according to my tests we are just 49 times faster than the regular DateTime.Now
只是添加时间跨度减慢了一点点,现在根据我的测试,我们只比常规
DateTime.Now
快49倍。现在
If we put this calculation in a separate function/class as suggested then calling the method slows us down even more and we are only 34 times faster. 如果我们按照建议将这个计算放在一个单独的函数/类中,那么调用该方法会使我们更慢,我们只会快34倍。
But even 34 times faster is a lot !!! 但即便快了34倍!
In short, Using DateTime.UtcNow
is much faster than DateTime.Now
简而言之,使用
DateTime.UtcNow
比DateTime.Now
快得多
The only way I found to improve the suggested class is to use inline code: DateTime.UtcNow + LocalUtcOffset
instead of calling the class method 我发现改进建议类的唯一方法是使用内联代码:
DateTime.UtcNow + LocalUtcOffset
而不是调用类方法
BTW trying to force the compiler to compile as inline by using [MethodImpl(MethodImplOptions.AggressiveInlining)]
didnt seem to speed things up. BTW试图强制编译器通过使用
[MethodImpl(MethodImplOptions.AggressiveInlining)]
内联编译似乎没有加快速度。
To answer in reverse order: 以相反的顺序回答:
2) I cannot think of a faster way. 2)我想不出更快的方法。
1) It would be worth checking if there are any framework improvements in the pipeline like they have just announced for System.IO 1)值得检查管道中是否有任何框架改进,就像他们刚刚宣布的System.IO一样
It's hard to be sure about safety but it's something that is crying out for a lot of unit tests. 很难确定安全性,但这是很多单元测试的问题。 Daylight savings comes to mind.
想到夏令时。 The System one is obviously very battle hardened while yours is not.
系统一显然是非常强硬的,而你的系统却没有。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.