代码之家  ›  专栏  ›  技术社区  ›  Hans

.NET核心中的日期时间精度

  •  0
  • Hans  · 技术社区  · 6 年前

    跟随埃里克·利珀特的 post 多年前的精密度 DateTime 我在使用Windows10的同一台计算机上运行了他的.NET核心和.NET框架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上的结果与预期一致:输出中的某些随机“相同”,这意味着 日期时间 对某些子级别不精确。

    然而,.NET核心上的结果完全不同:输出中没有“相同的”。不是两个 Ticks 有相同的价值。

    有什么解释?

    1 回复  |  直到 6 年前
        1
  •  0
  •   inquisitive    6 年前

    解释是,dot-net请求底层操作系统提供当前时间。操作系统询问底层硬件。在古代,主板上的硬件时钟(rtc)通常每15毫秒更新一次。 这个数字是从美国60Hz的交流线路频率得出的,在美国,电网保持足够精确。记住,那是“慢”计算机的时代,设计师们试图尽可能地提高每一点性能。因此,每当有人请求时间并传递值的缓存副本时,操作系统都不会向rtc咨询—该值的更新非常频繁。

    在这条线的某个地方,主板发生了变化,实时时钟变得更加精确。但是操作系统和它上面的所有东西都没有感觉到需要它。记住,H/W比软件发展得快得多,甚至直到今天,消费级软件仍然浪费大量原始H/W能力。因此,当dot net framework向操作系统请求时间时,即使H/W有能力,它也会返回不精确的数据。准确度确实从15毫秒发展到1毫秒以下,但事实就是这样。

    在Windows 8(Server 2012)中,人们最终意识到(1)应用程序可以用更精确的时间做得更好(2)计算机速度更快,因此每次咨询RTC都不再是问题(3)大量的程序和程序都被用于并且实际上依赖于不精确的时间行为。因此,他们(win 8)继续引入了一种稍微慢一点的新机制来获取最精确的时间数据,但保持了最初的实现不变。

    dot net总是使用老的和不精确的os函数 GetSystemTimeAsFileTime 当一个新表妹 GetSystemTimePreciseAsFileTime 出现在Win8中,点网Chise以向后兼容的方式,什么也没做。

    dot net core是对许多核心功能的全新重写,现在利用了高精度数据源。

    编辑

    如果当前时间是 13:14:15:12345 目前还不能保证物理学家和天文学家所看到的真实时间就是这样。你的计算机不是原子钟。当然不是同步好的时钟。唯一的意思是,如果两个事件发生在不同的时间戳上,那么一个事件肯定发生在另一个事件之前。在较旧的计算机中,事件(例如日志、文件、数据库txns等)的生成速率较低,因此顺序事件分配相同时间戳的可能性较低。这个新的时间系统迎合了现代的高比率活动,所以你可以将连续事件标记为不同的。尽管如此,对于两个非常接近的事件,总是有机会得到相同的时间戳。这最终是无法估量的。如果你需要纳秒级的测量(为什么),你需要不同的工具,比如 Stopwatch 而不是 System.DateTime