Java System.currentTimeMillis 与 System.nanoTime
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/351565/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
System.currentTimeMillis vs System.nanoTime
提问by mmcdole
Accuracy Vs. Precision
精度对比 精确
What I would like to know is whether I should use System.currentTimeMillis()or System.nanoTime()when updating my object's positions in my game? Their change in movement is directly proportional to the elapsed time since the last call and I want to be as precise as possible.
我想知道的是,在我的游戏中更新对象的位置时,我应该使用System.currentTimeMillis()还是System.nanoTime()?他们的运动变化与自上次通话以来经过的时间成正比,我希望尽可能精确。
I've read that there are some serious time-resolution issues between different operating systems (namely that Mac / Linux have an almost 1 ms resolution while Windows has a 50ms resolution??). I'm primarly running my apps on windows and 50ms resolution seems pretty inaccurate.
我读过不同操作系统之间存在一些严重的时间分辨率问题(即 Mac/Linux 的分辨率接近 1 毫秒,而 Windows 的分辨率为 50 毫秒??)。我主要是在 Windows 上运行我的应用程序,50 毫秒的分辨率似乎很不准确。
Are there better options than the two I listed?
还有比我列出的两个更好的选择吗?
Any suggestions / comments?
任何建议/意见?
采纳答案by dancavallaro
If you're just looking for extremely precise measurements of elapsed time, use System.nanoTime()
. System.currentTimeMillis()
will give you the most accurate possible elapsed time in milliseconds since the epoch, but System.nanoTime()
gives you a nanosecond-precise time, relative to some arbitrary point.
如果您只是在寻找经过时间的极其精确的测量,请使用System.nanoTime()
. System.currentTimeMillis()
将为您提供自纪元以来最准确的可能经过时间(以毫秒为单位),但System.nanoTime()
为您提供相对于某个任意点的纳秒级精确时间。
From the Java Documentation:
从 Java 文档:
public static long nanoTime()
Returns the current value of the most precise available system timer, in nanoseconds.
This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time. The value returned represents nanoseconds since some fixed but arbitrary origintime (perhaps in the future, so values may be negative). This method provides nanosecond precision, but not necessarily nanosecond accuracy. No guarantees are made about how frequently values change. Differences in successive calls that span greater than approximately 292 years (263nanoseconds) will not accurately compute elapsed time due to numerical overflow.
public static long nanoTime()
返回最精确的可用系统计时器的当前值,以纳秒为单位。
此方法只能用于测量经过的时间,与系统或挂钟时间的任何其他概念无关。返回的值表示自某个固定但任意的原始时间以来的纳秒(可能在未来,因此值可能为负)。此方法提供纳秒精度,但不一定提供纳秒精度。不保证值的更改频率。 由于数值溢出,跨越大约 292 年(2 63纳秒)的连续调用之间的差异将无法准确计算经过的时间。
For example, to measure how long some code takes to execute:
例如,要测量执行某些代码所需的时间:
long startTime = System.nanoTime();
// ... the code being measured ...
long estimatedTime = System.nanoTime() - startTime;
See also: JavaDoc System.nanoTime()and JavaDoc System.currentTimeMillis()for more info.
另请参阅:JavaDoc System.nanoTime()和JavaDoc System.currentTimeMillis()了解更多信息。
回答by Paul Morel
System.nanoTime()
isn't supported in older JVMs. If that is a concern, stick with currentTimeMillis
System.nanoTime()
旧的 JVM 不支持。如果这是一个问题,请坚持currentTimeMillis
Regarding accuracy, you are almost correct. On SOME Windows machines, currentTimeMillis()
has a resolution of about 10ms (not 50ms). I'm not sure why, but some Windows machines are just as accurate as Linux machines.
关于准确性,您几乎是正确的。在某些 Windows 机器上,currentTimeMillis()
分辨率约为 10 毫秒(不是 50 毫秒)。我不知道为什么,但有些 Windows 机器和 Linux 机器一样准确。
I have used GAGETimerin the past with moderate success.
我过去使用过GAGETimer并取得了一定的成功。
回答by Lawrence Dol
Yes, if such precision is required use System.nanoTime()
, but be aware that you are then requiring a Java 5+ JVM.
是的,如果需要这样的精度,请使用System.nanoTime()
,但请注意,您需要 Java 5+ JVM。
On my XP systems, I see system time reported to at least 100 microseconds278 nanosecondsusing the following code:
在我的 XP 系统上,我看到使用以下代码报告的系统时间至少为100 微秒278纳秒:
private void test() {
System.out.println("currentTimeMillis: "+System.currentTimeMillis());
System.out.println("nanoTime : "+System.nanoTime());
System.out.println();
testNano(false); // to sync with currentTimeMillis() timer tick
for(int xa=0; xa<10; xa++) {
testNano(true);
}
}
private void testNano(boolean shw) {
long strMS=System.currentTimeMillis();
long strNS=System.nanoTime();
long curMS;
while((curMS=System.currentTimeMillis()) == strMS) {
if(shw) { System.out.println("Nano: "+(System.nanoTime()-strNS)); }
}
if(shw) { System.out.println("Nano: "+(System.nanoTime()-strNS)+", Milli: "+(curMS-strMS)); }
}
回答by Michael Burr
Update by Arkadiy: I've observed more correct behavior of System.currentTimeMillis()
on Windows 7 in Oracle Java 8. The time was returned with 1 millisecond precision. The source code in OpenJDK has not changed, so I do not know what causes the better behavior.
Arkadiy更新:我System.currentTimeMillis()
在 Oracle Java 8 中观察到了Windows 7 上更正确的行为。时间以 1 毫秒的精度返回。OpenJDK 中的源代码没有改变,所以我不知道是什么导致了更好的行为。
David Holmes of Sun posted a blog article a couple years ago that has a very detailed look at the Java timing APIs (in particular System.currentTimeMillis()
and System.nanoTime()
), when you would want to use which, and how they work internally.
Sun 的 David Holmes 几年前发表了一篇博客文章,其中非常详细地介绍了 Java 计时 API(特别是System.currentTimeMillis()
和System.nanoTime()
)、何时需要使用哪个以及它们在内部如何工作。
Inside the Hotspot VM: Clocks, Timers and Scheduling Events - Part I - Windows
Hotspot VM 内部:时钟、定时器和调度事件 - 第一部分 - Windows
One very interesting aspect of the timer used by Java on Windows for APIs that have a timed wait parameter is that the resolution of the timer can change depending on what other API calls may have been made - system wide (not just in the particular process). He shows an example where using Thread.sleep()
will cause this resolution change.
Java 在 Windows 上为具有定时等待参数的 API 使用的计时器的一个非常有趣的方面是计时器的分辨率可以根据可能进行的其他 API 调用而改变 - 系统范围内(不仅仅是在特定进程中) . 他展示了一个示例,其中使用Thread.sleep()
会导致此分辨率更改。
回答by Jon Bright
I've had good experience with nanotime. It provides wall-clock time as two longs (seconds since the epoch and nanoseconds within that second), using a JNI library. It's available with the JNI part precompiled for both Windows and Linux.
我在nanotime 方面有很好的经验。它使用 JNI 库将挂钟时间提供为两个长(自纪元以来的秒数和该秒内的纳秒数)。它可用于为 Windows 和 Linux 预编译的 JNI 部分。
回答by gubby
Since no one else has mentioned this…
由于没有其他人提到这一点......
It is not safe to compare the results of System.nanoTime()
calls between different threads. Even if the events of the threads happen in a predictable order, the difference in nanoseconds can be positive or negative.
比较System.nanoTime()
不同线程之间的调用结果是不安全的。即使线程的事件以可预测的顺序发生,以纳秒为单位的差异也可能是正数或负数。
System.currentTimeMillis()
is safe for use between threads.
System.currentTimeMillis()
在线程之间使用是安全的。
回答by sarvesh
one thing here is the inconsistency of the nanoTime method.it does not give very consistent values for the same input.currentTimeMillis does much better in terms of performance and consistency,and also ,though not as precise as nanoTime,has a lower margin of error,and therefore more accuracy in its value. i would therefore suggest that you use currentTimeMillis
这里的一件事是 nanoTime 方法的不一致。它不会为相同的输入提供非常一致的值。currentTimeMillis 在性能和一致性方面做得更好,而且虽然不如 nanoTime 精确,但误差幅度较小,因此其值更准确。因此,我建议您使用 currentTimeMillis
回答by KarlU
As others have said, currentTimeMillis is clock time, which changes due to daylight saving time, users changing the time settings, leap seconds, and internet time sync. If your app depends on monotonically increasing elapsed time values, you might prefer nanoTime instead.
正如其他人所说,currentTimeMillis 是时钟时间,它会因夏令时、用户更改时间设置、闰秒和互联网时间同步而变化。如果您的应用依赖于单调递增的经过时间值,您可能更喜欢 nanoTime。
You might think that the players won't be fiddling with the time settings during game play, and maybe you'd be right. But don't underestimate the disruption due to internet time sync, or perhaps remote desktop users. The nanoTime API is immune to this kind of disruption.
您可能认为玩家在玩游戏时不会摆弄时间设置,也许您是对的。但不要低估互联网时间同步或远程桌面用户造成的中断。nanoTime API 不受这种中断的影响。
If you want to use clock time, but avoid discontinuities due to internet time sync, you might consider an NTP client such as Meinberg, which "tunes" the clock rate to zero it in, instead of just resetting the clock periodically.
如果您想使用时钟时间,但要避免因 Internet 时间同步而导致的中断,您可以考虑使用 Meinberg 等 NTP 客户端,它可以“调整”时钟频率以将其归零,而不仅仅是定期重置时钟。
I speak from personal experience. In a weather application that I developed, I was getting randomly occurring wind speed spikes. It took a while for me to realize that my timebase was being disrupted by the behavior of clock time on a typical PC. All my problems disappeared when I started using nanoTime. Consistency (monotonicity) was more important to my application than raw precision or absolute accuracy.
我从个人经历说起。在我开发的天气应用程序中,我得到了随机发生的风速峰值。我花了一段时间才意识到我的时基被典型 PC 上的时钟时间行为打乱了。当我开始使用 nanoTime 时,我所有的问题都消失了。对我的应用来说,一致性(单调性)比原始精度或绝对精度更重要。
回答by Thomas W
For game graphics & smooth position updates, use System.nanoTime()
rather than System.currentTimeMillis()
. I switched from currentTimeMillis() to nanoTime() in a game and got a major visual improvement in smoothness of motion.
对于游戏图形和平滑的位置更新,使用System.nanoTime()
而不是System.currentTimeMillis()
. 我在游戏中从 currentTimeMillis() 切换到 nanoTime() 并在运动平滑度方面获得了重大的视觉改进。
While one millisecond may seem as though it should already be precise, visually it is not. The factors nanoTime()
can improve include:
虽然一毫秒看起来应该已经很精确了,但在视觉上却并非如此。nanoTime()
可以改善的因素包括:
- accurate pixel positioning below wall-clock resolution
- ability to anti-alias between pixels, if you want
- Windows wall-clock inaccuracy
- clock jitter (inconsistency of when wall-clock actually ticks forward)
- 低于挂钟分辨率的精确像素定位
- 如果需要,可以在像素之间消除锯齿
- Windows 挂钟不准确
- 时钟抖动(挂钟实际向前滴答的时间不一致)
As other answers suggest, nanoTime does have a performance cost if called repeatedly -- it would be best to call it just once per frame, and use the same value to calculate the entire frame.
正如其他答案所暗示的那样,如果重复调用 nanoTime 确实会产生性能成本 - 最好每帧只调用一次,并使用相同的值来计算整个帧。
回答by Ricardo Gasca
System.currentTimeMillis()
is not safe for elapsed time because this method is sensitive to the system realtime clock changes of the system.
You should use System.nanoTime
.
Please refer to Java System help:
System.currentTimeMillis()
对于经过的时间是不安全的,因为这种方法对系统的系统实时时钟变化很敏感。你应该使用System.nanoTime
. 请参考 Java 系统帮助:
About nanoTime method:
关于纳米时间方法:
.. This method provides nanosecond precision, but not necessarily nanosecond resolution (that is, how frequently the value changes) - no guarantees are made except that the resolution is at least as good as that of currentTimeMillis()..
.. 此方法提供纳秒精度,但不一定提供纳秒分辨率(即值更改的频率)- 除了分辨率至少与 currentTimeMillis() 一样好外,不做任何保证。
If you use System.currentTimeMillis()
your elapsed time can be negative (Back <-- to the future)
如果你使用System.currentTimeMillis()
你的流逝时间可能是负数(返回 <-- 到未来)