System.currentTimeMillis vs System.nanoTime

2018-12-31 03:26发布

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.

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.

Are there better options than the two I listed?

Any suggestions / comments?

10条回答
裙下三千臣
2楼-- · 2018-12-31 03:44

System.nanoTime() isn't supported in older JVMs. If that is a concern, stick with 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.

I have used GAGETimer in the past with moderate success.

查看更多
与风俱净
3楼-- · 2018-12-31 03:47

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.


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.

Inside the Hotspot VM: Clocks, Timers and Scheduling Events - Part I - 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.

查看更多
看风景的人
4楼-- · 2018-12-31 03:50

Thread-Safety

Since no one else has mentioned this…

Not Safe

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.

Safe

System.currentTimeMillis() is safe for use between threads.

查看更多
怪性笑人.
5楼-- · 2018-12-31 03:50

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.

While one millisecond may seem as though it should already be precise, visually it is not. The factors nanoTime() can improve include:

  • 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)

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.

查看更多
登录 后发表回答