Han*_*ans 2 .net c# datetime .net-core
继 Eric Lippert多年前关于 精度的帖子DateTime之后,我在装有 Windows 10 的同一台计算机上对 .netcore 和 .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);
}
Run Code Online (Sandbox Code Playgroud)
.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)继续引入一种新的稍微慢一些的机制来获取最精确的时间数据,但保持原始实现不变。
dot net一直使用旧的、不精确的操作系统功能GetSystemTimeAsFileTime,当win 8中出现新表弟时GetSystemTimePreciseAsFileTime,dot net选择走向后兼容的方式,什么也没做。
Dot net core 是对许多核心功能的全新重写,现在利用了高精度数据源。
如果当前时间是13:14:15:123456,仍然不能保证物理学家和天文学家所看到的真正的时间。您的计算机不是原子钟。当然也不是一个同步良好的时钟。它唯一的意思是,如果两个事件在不同的时间戳发生,那么一个事件肯定在另一个事件之前发生。在较旧的计算机中,事件(例如日志、文件、数据库 txns 等)的生成率较低,因此顺序事件被分配相同时间戳的可能性很小。这个新的时间系统迎合现代高频率活动,以便您可以将连续事件标记为不同的。尽管如此,对于两个非常接近的事件,总是有可能出现相同的时间戳。这最终是不可避免的。如果您需要纳秒级测量(为什么),您需要不同的工具,例如Stopwatch和System.DateTime。
| 归档时间: |
|
| 查看次数: |
1886 次 |
| 最近记录: |