For a long time I measured passed time using System.currentTimeMillis()
and only recently figured out that I can also use nanoTime()
. However some results were not what I expected, as nanoTime
measures the time from an arbitrary point in time instead of 01-01-1970
as currentTimeMillis
does.
From the JavaDoc for 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 time (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 (263 nanoseconds) will not accurately compute elapsed time due to numerical overflow.
For example, to measure how long some code takes to execute:
long startTime = System.nanoTime(); // ... the code being measured ... long estimatedTime = System.nanoTime() - startTime;
I am confused by the arbitrary part. Measuring the passed time is only accurate if the reference timestamp is the same for both calls. However in the API documentation this is not guaranteed. I think that this was the cause for my mentioned issues. The time that is used is an implementation detail and therefore I cannot rely on it.
I am wondering about, when I can make good use of nanoTime
and in which cases it goes horribly wrong. The main use cases that come to mind are:
nanoTime
timestamps from different threadsnanoTime
timestamps from different instances of the same JVM (think, serialized timestamp from a previous application run, or passed as part of a message to a different JVM)nanoTime
timestamps in different JVM implementationsThere are some posts here on StackOverflow that address part of the issue, but largely leave the issue of the choosing of the time open:
Especially the link in the last one makes it clear that there are limitations when nanoTime
can be used, but without knowing these limitations exactly it seems inherently unsafe to use it at all as the functionality that is built upon it may fail.
The documentation should perhaps be explicit about this, but what they mean by "fixed but arbitrary" is that within the same JVM (i.e. within the same running JVM instance), the reference value is fixed.
So (1) is safe, but not beyond that.
Anything beyond that is depending on implementation quirks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With