Reputation: 198188
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
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
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
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