Freewind
Freewind

Reputation: 198188

System.nanoTime() on windows XP

I just found System.currentTimeMillis is not accurate on windows XP, now I tried System.nanoTime() with the same code.

Since 1ms = 1,000,000ns, so I think the result should be 15,000,000ns, but it's not.

See the sample code:

public class NanoTime {
    public static void main(String[] args) {
        long start = 0;
        long end = 0;
        while (true) {
            if (start == 0) {
                start = System.nanoTime();
            } else {
                long current = System.nanoTime();
                if (current != start) {
                    end = current;
                    break;
                }
            }
        }
        System.out.println("The time interval of your OS: " + (end - start) + "ns");
    }
}

The result is:

The time interval of your OS: 655ns

Seems it's much better than System.currentTimeMillis(). But why? Can we believe this result?

Upvotes: 0

Views: 679

Answers (3)

Yahia
Yahia

Reputation: 70369

If your Windows XP has SP3 then you can believe that result... on Windows the JVM implements nanoTime() internally using QueryPerformanceCounter/QueryPerformanceFrequency API which is basically located in HAL (Hardware abstraction layer) and uses some CPU-internal interval instructions which are rather accurate... it is only good for interval measurements NOT for time handling...

For a more elaborate description see http://blogs.oracle.com/dholmes/entry/inside_the_hotspot_vm_clocks and http://juliusdavies.ca/posix_clocks/clock_realtime_linux_faq.html

EDIT - as per comment:

The above mentioned function are used by the JVM itself internally when nanoTime is called which has absolutely NOTHING to do with JNI - they are not exposed to Java code!

EDIT 2 - as per comments:

nanoTime() is the right tool to measure elapsed time accurately while currentTimeMillis is the right tool to handle absolute time.

Upvotes: 4

JB Nizet
JB Nizet

Reputation: 691635

The best way to know what a method does is to read its javadoc. Not to guess what it does using experiments.

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.

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1499790

Why?

Because it's not trying to be accurate in the same way.

From the Javadocs:

This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time.

So yes, it's good for measuring elapsed time accurately. It's not good at giving you an absolute time, and you won't get that more accurately than System.currentTimeMillis(), at least without coordinating explicitly with NTP etc. Use the right tool for the job, and don't design a system which needs a hugely accurate absolute time.

Upvotes: 4

Related Questions