继Eric Lippert在post的精确度之后post年,我在与.NET 10相同的机器上运行了.NET核心和.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的结果与预期的一样:输出中的一些随机"same"意味着 DateTime
对某些子级别不精确 .
但是,.NET核心的结果完全不同:输出中没有"same" . 不是两个 Ticks
具有相同的值 .
会有什么解释?
1 回答
解释是,dot net要求底层操作系统获取当前时间 . 操作系统询问底层硬件 . 在古代,主板上的硬件时钟(RTC)用于在大约15毫秒内更新一次 . 该数字来自美国的60hz AC线路频率,电网保持足够精确 . 请记住,那些是“慢”计算机的时代,设计师试图在他们可能的每一点性能中 balancer . 因此,每当有人要求时间并传递值的缓存副本时,操作系统就不会咨询RTC - 这种情况经常更新 .
在某个地方,主板不断发展,RTC变得更加精准 . 但操作系统和其上的所有东西都没有感觉到它的需要 . 记住h / w的发展速度远远超过软件,甚至直到白天,消费级软件都浪费了很大一部分原始h / w能力 . 因此,当dot net框架询问操作系统的时间时,即使h / w能够,它也会收回不精确的数据 . 准确度确实从15毫秒发展到1毫秒以下,但就是这样 .
来到Windows 8(服务器2012),终于意识到(1)应用程序可以用更精确的时间做得更好(2)计算机速度快,所以每次咨询RTC不再是问题(3)大量的程序员和程序是习惯和行为依赖于不精确的时间行为 . 因此他们(赢得8)继续引入一种新的稍慢的机制来获得最精确的时间数据,但保持原始实现不变 .
Dot net一直使用旧的和不精确的操作系统功能
GetSystemTimeAsFileTime
当一个新的表兄GetSystemTimePreciseAsFileTime
出现在win 8中时,点网chise向后兼容的方式并没有做任何事情 .Dot net core是许多核心功能的重写,现在利用了高精度数据源 .
编辑
如果当前时间是13:14:15:123456,那么仍然无法保证物理学家和天文学家所看到的实际真实时间 . 你的电脑不是原子钟 . 当然不是一个很好的同步时钟 . 它唯一意味着如果两个事件发生在不同的时间戳,那么一个事件肯定发生在另一个事件之前 . 在较旧的计算机中,事件的生成速率(日志,文件,数据库txns等)较低,因此为顺序事件分配相同时间戳的可能性很小 . 这个新的时间系统迎合了现代高速率活动,因此您可以将顺序事件标记为不同 . 仍然有两个非常接近的事件,总会有相同时间戳的机会 . 这最终是不可避免的 . 如果你需要纳秒级别测量(为什么)你需要不同的工具,如
Stopwatch
而不是System.DateTime