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?
System.nanoTime()
isn't supported in older JVMs. If that is a concern, stick withcurrentTimeMillis
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.
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()
andSystem.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.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.For game graphics & smooth position updates, use
System.nanoTime()
rather thanSystem.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: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.