处理时间测量的最佳方法是什么?

这个问题在这里已经有了答案:

  • 我如何在Java中编写正确的微基准测试? 11个答案

  • 你过分关注精度的不重要的细节。 如果您想测量/分析某些操作的执行情况,则必须确保这些操作运行足够长时间,以使测量不受一次性工件,线程调度时序,垃圾回收或热点优化中的微小差异的影响。 在大多数情况下,如果差异小于毫秒级别,那么从它们得出结论是没有用的。

    更重要的方面是这些工具是否为您的任务而设计。 System.currentTimeMillis()和所有其他基于壁钟的API,无论它们是否基于currentTimeMillis() ,都旨在为您提供一个时钟,该时钟旨在与地球的旋转及其围绕太阳的路径同步,该时钟负载它承担着闰秒和其他修正措施的负担,而不是说你的计算机的时钟可能与挂钟不同步并得到纠正,例如通过NTP更新,在最坏的情况下,当你跳到右边时试图衡量你的流逝时间,甚至可能倒退。

    相比之下, System.nanoTime()旨在衡量流逝的时间(正是你想要做的),没有别的。 由于其返回值具有未指定的来源,甚至可能为负值,因此只有通过此方法返回的两个值之间的差异才具有任何意义。 你甚至可以在文档中找到它:

    只有在计算在同一个Java虚拟机实例中获得的两个此类值之间的差异时,此方法返回的值才有意义。

    所以当你想测量和处理你的方法执行或事务的流逝时间时, System.nanoTime()就是要走的路。 当然,它只提供了一个裸long价值,但不清楚你想要什么样的API支持。 由于时间点不相关,甚至在这里分散注意力,因此只会有一个持续时间,您可以将其转换为其他时间单位,或者,如果要使用新时间API,则可以使用Duration.ofNanos(long)创建Duration对象Duration.ofNanos(long) ,允许您添加和减去持续时间值并对其进行比较,但没有太多可以做的事情。 你不能将它们与墙上时钟或基于日历的持续时间混合在一起......

    作为最后一点,该文档对于该限制有点不准确。 如果计算System.nanoTime()返回的两个值之间的差值,则数值溢出本身并不坏。 由于计数器具有未指定的来源,因此操作的Long.MAX_VALUE可能接近Long.MAX_VALUE而最终值接近Long.MIN_VALUE因为JVM的计数器发生溢出。 在这种情况下,计算差值会导致另一次溢出,从而产生一个正确的差值。 但是,如果将这种差异存储在带符号的long ,它最多可以保存2⁶3纳秒,将差异限制为最大292年,但如果将其作为无符号long来处理,例如通过Long.compareUnsignedLong.toUnsignedString ,则可以处理偶数2?4纳秒的持续时间,换句话说,如果您的计算机没有中断,可以采用这种方式测量长达584年的时间。


    我建议使用ThreadMXBean getThreadCpuTime (另请参阅https://stackoverflow.com/a/7467299/185031)。 如果你想测量一个方法的执行时间,你大部分时间对挂钟没有那么多兴趣,但更多的是关注CPU执行时间。

    链接地址: http://www.djcxy.com/p/86541.html

    上一篇: Best approach for dealing with time measures?

    下一篇: Java faster than C