Java 系统的精度与精度。纳米时间()

Java 系统的精度与精度。纳米时间(),java,nanotime,Java,Nanotime,以下是我的文档(重点是我的) 此方法只能用于测量经过的时间,与系统或挂钟时间的任何其他概念无关。返回的值表示从某个固定但任意的时间开始的纳秒(可能在将来,因此值可能是负数)此方法提供纳秒精度,但不一定是纳秒精度。不保证值的变化频率 在我看来,这可以用两种不同的方式来解释: 上面粗体中的句子指的是单个返回值。然后,精度和准确度将在数值意义上被理解。也就是说,精度是指有效数字的数量——截断的位置,精度是指数字是否正确(如顶部答案中所述) ) 上面粗体的句子是指方法本身的能力。然后,精确性和精确性将被

以下是我的文档(重点是我的)

此方法只能用于测量经过的时间,与系统或挂钟时间的任何其他概念无关。返回的值表示从某个固定但任意的时间开始的纳秒(可能在将来,因此值可能是负数)此方法提供纳秒精度,但不一定是纳秒精度。不保证值的变化频率

在我看来,这可以用两种不同的方式来解释:

  • 上面粗体中的句子指的是单个返回值。然后,精度和准确度将在数值意义上被理解。也就是说,精度是指有效数字的数量——截断的位置,精度是指数字是否正确(如顶部答案中所述) )

  • 上面粗体的句子是指方法本身的能力。然后,精确性和精确性将被理解为如镖靶类比所示 ( ). 因此,低精度,高精度=>错误的值会以高精度重复命中:想象物理时间静止不动,连续调用nanoTime()返回相同的数值,但它与自参考时间以来的实际运行时间相差一定的偏移量

  • 哪种解释是正确的?我的观点是,解释2意味着使用nanoTime()测量时间差(减去两个返回值)将正确到纳秒(因为测量中的恒定误差/偏移将被消除),虽然解释1不能保证测量之间的一致性,因此不一定意味着时间差测量的高精度


    已于2013年4月15日更新:的Java 7文档已更新,以解决可能与先前措辞混淆的问题

    返回正在运行的Java虚拟机的高分辨率时间源的当前值(以纳秒为单位)

    此方法只能用于测量经过的时间,与系统或挂钟时间的任何其他概念无关。返回的值表示自某个固定但任意的起始时间起的纳秒(可能在将来,因此值可能为负数)。Java虚拟机实例中此方法的所有调用都使用相同的源代码;其他虚拟机实例可能使用不同的源

    此方法提供纳秒精度,但不一定是纳秒分辨率(即值变化的频率)-除了分辨率至少与其他方法一样好外,不作任何保证

    由于数字溢出,连续调用的差异超过大约292年(263纳秒)将无法正确计算经过的时间

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


    第一种解释是正确的。在大多数系统上,三个最低有效数字始终为零。这实际上提供了微秒级的精度,但报告的精度为纳秒级


    事实上,现在我再看一遍,你的第二种解释也是对正在发生的事情的有效描述,也许更是如此。想象冻结的时间,报告将始终是相同的错误纳秒数,但如果理解为整数微秒数,则报告是正确的。

    在Clojure命令行中,我得到:

    user=> (- (System/nanoTime) (System/nanoTime))
    0
    user=> (- (System/nanoTime) (System/nanoTime))
    0
    user=> (- (System/nanoTime) (System/nanoTime))
    -641
    user=> (- (System/nanoTime) (System/nanoTime))
    0
    user=> (- (System/nanoTime) (System/nanoTime))
    -642
    user=> (- (System/nanoTime) (System/nanoTime))
    -641
    user=> (- (System/nanoTime) (System/nanoTime))
    -641
    
    因此,本质上,
    nanoTime
    并不是每纳秒更新一次,这与人们直观地期望它的精度相反。在Windows系统中,它在引擎盖下使用了
    QueryPerformanceCounter
    API(根据),实际上它的分辨率大约为640ns(在我的系统中!)


    请注意,
    nanoTime
    本身不能有任何准确性,因为它的绝对值是任意的。只有连续的
    nanoTime
    调用之间的差异才有意义。这种差异的准确度大约为1微秒。
    System.currentTimeMillis()
    System.nanoTime()
    之间差异的一个有趣特征是
    System.nanoTime()
    不会随着挂钟的变化而变化。我在Windows虚拟机上运行代码,该虚拟机具有严重的时间漂移
    System.currentTimeMillis()
    可以在NTP校正漂移时,每次向前或向后跳1-2秒,使准确的时间戳变得毫无意义。(Windows 2003、2008 VPS版本)

    然而,
    System.nanoTime()
    不受更改挂钟时间的影响,因此您可以获取通过NTP检索到的时间,并基于
    System.nanoTime()
    应用更正,因为上次检查了NTP,并且在不利的挂钟条件下,您的时间比
    System.currentTimeMillis()
    精确得多


    这当然是违反直觉的,但知道这一点很有用

    如果像我这样的人一次又一次地来阅读这个问题,仍然能够理解它,这里有一个更简单(我希望)的解释

    精度
    是指您保留的位数。以下各项:

    long start = System.nanoTime();
    long end   = System.nanoTime();
    
    将是一个精确的数字(许多数字)

    由于
    准确度
    仅与某物进行比较,因此单独调用
    System.nanoTime
    毫无意义,因为它的值是任意的,不依赖于我们可以测量的东西。区分其准确性的唯一方法是对其进行两次不同调用,因此:

     long howMuch = end - start;
    
    不会有纳秒的精确度。事实上,在我的机器上,差异是0.2-0.3微秒

    据我所知,那