Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passed time with nanoTime()

Tags:

java

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:

  • Comparing nanoTime timestamps from different threads
  • Comparing nanoTime 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)
  • Comparing nanoTime timestamps in different JVM implementations

There are some posts here on StackOverflow that address part of the issue, but largely leave the issue of the choosing of the time open:

  • System.currentTimeMillis vs System.nanoTime
  • Is System.nanoTime() completely useless?

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.

like image 901
hotzst Avatar asked Nov 09 '22 21:11

hotzst


1 Answers

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.

like image 168
Daniel Martin Avatar answered Nov 14 '22 23:11

Daniel Martin