很长一段时间我使用System.currentTimeMillis()
测量了通过时间,但最近才发现我也可以使用nanoTime()
。但是有些结果并非我的预期,因为nanoTime
衡量的是从任意时间点开始的时间,而不是01-01-1970
的{{1}}。
返回最精确的可用系统计时器的当前值, 以纳秒为单位。
此方法只能用于测量经过的时间而不是 与系统或挂钟时间的任何其他概念有关。价值 返回表示纳秒,因为某些固定但是任意时间 (也许在未来,所以价值观可能是负面的)。这种方法 提供纳秒级精度,但不一定是纳秒级 准确性。不保证值的变化频率。 连续调用的差异大于约 292年(263纳秒)将无法准确计算经过的时间 由于数字溢出。
例如,要测量一些代码执行所需的时间:
currentTimeMillis
我对任意部分感到困惑。只有两个呼叫的参考时间戳相同时,才能测量通过的时间。但是在API文档中,这不能保证。我认为这是我提到的问题的原因。使用的时间是一个实现细节,因此我不能依赖它。
我想知道,当我可以充分利用long startTime = System.nanoTime();
// ... the code being measured ...
long estimatedTime = System.nanoTime() - startTime;
时,在哪些情况下它会出现可怕的错误。想到的主要用例是:
nanoTime
时间戳nanoTime
时间戳(想想,来自先前应用程序运行的序列化时间戳,或作为消息的一部分传递到不同的JVM)nanoTime
时间戳StackOverflow上有一些帖子解决了部分问题,但很大程度上留下了选择开放时间的问题:
特别是the link在最后一个中明确表示存在限制何时可以使用 nanoTime
,但是如果不完全了解这些限制,那么使用它本身就是不安全的因为基于它的功能可能会失败。
答案 0 :(得分:1)
文档也许应该是明确的,但是它们的意思是“固定但任意”是在同一个JVM中(即在同一个运行的JVM实例中),参考值是固定的。
所以(1)是安全的,但不能超越它。
除此之外的任何事情都取决于实施的怪癖。
答案 1 :(得分:0)
共享CPU(普通计算机)上的计时永远不会完全正确。您不知道您的进程何时实际在CPU上运行(而不是其他100个进程中的一个)。它只能检查运行的时间。
您测量的时间单位越小,这种不准确性就越明显。