Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare two nano time values? [javadoc confusion]

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:

  1. Why would one check if t1 < t0 if t1 was taken after t0? My understanding is that nano time is always increasing. So, I would rather check t1 > t0.
  2. Let's suppose that's a typo, and they meant the correct check is 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?

like image 230
Evgeni Avatar asked Nov 30 '15 10:11

Evgeni


People also ask

Is system nanoTime () reliable?

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

Is system currentTimeMillis accurate?

currentTimeMillis() . This method reports current time with the millisecond accuracy. One may think that, because of this, the performance of this method is irrelevant.

What is nanoTime in Java?

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.

Is nanoTime monotonic?

In comparison, System. nanoTime() is monotonic so we should have used this one.


2 Answers

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.

like image 71
Mike Nakis Avatar answered Sep 20 '22 02:09

Mike Nakis


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.

like image 41
Andremoniy Avatar answered Sep 18 '22 02:09

Andremoniy