【发布时间】:2018-06-14 08:35:15
【问题描述】:
我刚刚注意到我们的一个单元测试占用了十秒钟。在玩弄它之后,我创建了一个最小的 linqpad 示例来重现它:
void Main()
{
Stopwatch sw = new Stopwatch();
sw.Start();
var timeZone = TimeZoneInfo.Local;
for(int i=0; i<10000; i++)
{
//var dateTime = TimeZoneInfo.ConvertTime(DateTime.UtcNow, timeZone);
var dateTime = TimeZoneInfo.ConvertTime(DateTime.MinValue, timeZone);
}
sw.Stop();
(sw.ElapsedMilliseconds + " ms").Dump();
}
这在我的 PC 或我们的构建 PC 上需要 40 秒。如果我使用 DateTime.UtcNow,则需要 15 毫秒。
有什么原因或解决方法吗?
编辑:按照 cmets 中的建议,我反编译了 TimeZoneInfo,并且 DateTime.MinValue 有一个特殊情况:
static public DateTime ConvertTime(DateTime dateTime, TimeZoneInfo destinationTimeZone) {
// Special case to give a way clearing the cache without exposing ClearCachedData()
if (dateTime.Ticks == 0) {
ClearCachedData();
}
看起来(测试?)代码每次使用 DateTime.MinValue 调用时都会清除缓存。
留下为什么会发生这种情况的问题。
【问题讨论】:
-
我猜你可以使用一些 Dll 反编译工具来检查你自己的代码,看看这两个属性是如何在幕后生成的。
-
好点,我去看看。
-
// Special case to give a way clearing the cache without exposing ClearCachedData()嗯,这有点邪恶。特别是因为它实际上是暴露的。不知何故,这通过了代码审查。幸运的是,从伯利恒转换一个古老的日期并不常见:) -
我们有很多命中的原因是 DateTime.MinValue 是默认值,它与使用 new DateTime() 相同。
-
“神奇值”出错的频率非常惊人。但是,是的,通常不止一个程序员认为它足够神奇。永远支持
Nullable<DateTime>这里。