跟随埃里克·利珀特的post多年前的精确度DateTime
,我在装有 Windows 10 的同一台计算机上在 .net core 和 .NET Framework 4.5.2 上运行了他的测试。
var n = 1000;
int i = 0;
long[] diffs = new long[n];
while (i++ < n-1)
{
if (ticks != DateTime.Now.Ticks)
{
var newTicks = DateTime.UtcNow.Ticks;
var diff = newTicks - ticks;
diffs[i] = diff;
ticks = newTicks;
}
}
foreach (var d in diffs)
{
if (d == 0)
Console.WriteLine("same");
else
Console.WriteLine(d);
}
.NET Framework 4.5.2 上的结果符合预期:输出中有一些随机“相同”,这意味着DateTime
对于某些子级别并不精确。
然而,.NET core 上的结果完全不同:输出中没有“相同”。不是两个Ticks
具有相同的值。
该怎么解释呢?
解释是,.net 向底层操作系统询问当前时间。操作系统询问底层硬件。在古代,主板上的硬件时钟 (RTC) 每约 15 毫秒更新一次。
这个数字是根据美国 60Hz 交流线路频率得出的,电网保持足够准确。请记住,那是计算机“慢”的时代,设计师们试图尽可能地发挥每一点性能。因此,每次有人请求时间时,操作系统都不会咨询 RTC,并传递该值的缓存副本 - 该副本很少更新。
后来,主板不断发展,RTC 变得更加精确。但操作系统和其之上的所有东西并不觉得有必要。请记住,硬件的发展速度远远快于软件,甚至直到今天,消费级软件也浪费了很大一部分原始硬件功能。因此,当.net框架向操作系统请求时间时,即使硬件有能力,它也会返回不精确的数据。准确度确实从 15 毫秒发展到了 1 毫秒以下,但仅此而已。
到了windows 8(server 2012),终于意识到(1)应用程序可以通过更精确的时间做得更好(2)计算机速度很快,所以每次查询RTC不再是问题(3)大量的程序员和程序习惯并且实际上依赖于不精确的时间行为。因此他们(win 8)继续引入一种新的稍微慢一些的机制来获取最精确的时间数据,但保持原始实现不变。
点网一直使用较旧且不精确的操作系统功能GetSystemTimeAsFileTime
当一个新表弟GetSystemTimePreciseAsFileTime
出现在win 8中,.net选择走向后兼容的方式,什么也没做。
Dot net core 是对许多核心功能的全新重写,现在利用了高精度数据源。
Edit
如果当前时间是13:14:15:123456,仍然不能保证物理学家和天文学家所看到的真正的时间。您的计算机不是原子钟。当然也不是一个同步良好的时钟。它唯一的意思是,如果两个事件在不同的时间戳发生,那么一个事件肯定在另一个事件之前发生。在较旧的计算机中,事件(例如日志、文件、数据库 txns 等)的生成率较低,因此顺序事件被分配相同时间戳的可能性很小。这个新的时间系统迎合现代高频率活动,以便您可以将连续事件标记为不同的。尽管如此,对于两个非常接近的事件,总是有可能出现相同的时间戳。这最终是不可避免的。如果您需要纳秒级测量(为什么),您需要不同的工具,例如Stopwatch
并不是System.DateTime
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)