I have read the javadoc for System.nanoTime()
and it all seems clear. Until I reached the final paragraph:
To compare two nanoTime values
long t0 = System.nanoTime();
...
long t1 = System.nanoTime();
one should use t1 - t0 < 0, not t1 < t0, because of the possibility of numerical overflow.
There are two things that are unclear to me:
t1 < t0
if t1
was taken after t0
? My understanding is that nano time is always increasing. So, I would rather check t1 > t0
.t1 - t0 > 0
. I still don't get it why that is the correct way of checking and not t1 > t0
. They mention the numerical overflow and I don't quite get what they mean. Regarding the numerical overflow, here's what is mentioned:Differences in successive calls that span greater than approximately 292 years (2^63 nanoseconds) will not correctly compute elapsed time due to numerical overflow.
OK, so since the nano time is stored as a long value, it will eventually overflow in 292 years. And what happens next? Does it start from the beginning, i.e. the lowest negative value -2^63? Or does it stop measuring and returns (2^63 - 1) always?
nanoTime() is a great function, but one thing it's not: accurate to the nanosecond. The accuracy of your measurement varies widely depending on your operation system, on your hardware and on your Java version. As a rule of thumb, you can expect microsecond resolution (and a lot better on some systems).
currentTimeMillis() . This method reports current time with the millisecond accuracy. One may think that, because of this, the performance of this method is irrelevant.
nanoTime. public static long nanoTime() Returns the current value of the running Java Virtual Machine's high-resolution time source, 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.
In comparison, System. nanoTime() is monotonic so we should have used this one.
You are right, the parts of the documentation that you quoted seem to be a bit confused.
However, the part of the documentation that counts is this:
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 origin time (perhaps in the future, so values may be negative). The same origin is used by all invocations of this method in an instance of a Java virtual machine; other virtual machine instances are likely to use a different origin.
(emphasis added by me.)
What this means is that you do not have any guarantees that your code will not happen to be running at the time that the yielded long value will happen to flip from positive to negative.
There is nothing that guarantees that this will happen in 300 years from now, it may happen today.
Currently, my JVM returns some number like 3496793269188, but it could, if it wanted to, be returning some number very close to 9223372036854775807, (which is Long.MAX_VALUE
,) which would make a flip from positive to negative imminent.
So, you should take all necessary precautions.
Well, javadoc
says truth. Consider such example:
long t0 = Long.MAX_VALUE;
long t1 = Long.MIN_VALUE;
System.out.println(t1 < t0);
System.out.println(t1 - t0 < 0);
It will give
true
false
while mathematically both expressions are true. But in our case we know, that negative value of time
means, that it is overflowed, hence it should be really greater then positive number.
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