System.nanoTime() inaccurate?
Hi,
I'm trying to do some accurate timing over long periods. I require at least sub 5ms accuracy over a number of years. Because System.currentTimeMillis() is only accurate to the system accuracy (which on Windows could be around 55ms) I am using the nanosecond timer as an offset from a base value derived from System.currentTimeMillis().
In theory, this should all work, and does... but only approximately. I am finding that the nanoTime "drifts" out by approx 140000ns for every second of real time, when measured against the millisecond timer. Obviously it doesn't take long before this becomes a problem.
So it appears that a nanoTime() nanosecond is not actually a nanosecond (at least on Windows/Intel), but actually slightly less.
Anyone else noticed this? Is it a bug?
Can anyone suggest a decent platform-independent solution?
Cheers,
Chris.
[902 byte] By [
chris0a] at [2007-10-2 18:22:18]

Running this little program:import java.text.DecimalFormat;
public class Test {
static final long billion = 1000 * 1000 * 1000;
static final DecimalFormat format = new DecimalFormat("#,###");
public static void main(String[] args) throws Exception {
for (int i = 0; i < 60; ++i) {
long millisStart = System.currentTimeMillis();
long nanosStart = System.nanoTime();
long nanosDiff = 0;
do {
nanosDiff = System.nanoTime() - nanosStart;
} while (nanosDiff < 10 * billion);
long millisDiff = System.currentTimeMillis() - millisStart;
System.out.println(format.format(millisDiff) + "ms versus " +
format.format(nanosDiff) + "ns vields diff of " +
format.format(((millisDiff * 1000000) - nanosDiff)) + "ns");
}
}
}
I get the following output:
9,983ms versus 10,000,000,559ns vields diff of -17,000,559ns
9,984ms versus 10,000,000,559ns vields diff of -16,000,559ns
9,973ms versus 10,000,000,279ns vields diff of -27,000,279ns
9,974ms versus 10,000,000,000ns vields diff of -26,000,000ns
9,983ms versus 10,000,000,000ns vields diff of -17,000,000ns
9,974ms versus 10,000,000,279ns vields diff of -26,000,279ns
9,993ms versus 10,000,000,279ns vields diff of -7,000,279ns
9,974ms versus 10,000,001,117ns vields diff of -26,001,117ns
9,983ms versus 10,000,000,559ns vields diff of -17,000,559ns
9,974ms versus 10,000,000,000ns vields diff of -26,000,000ns
9,983ms versus 10,000,587,784ns vields diff of -17,587,784ns
9,974ms versus 10,000,000,000ns vields diff of -26,000,000ns
9,983ms versus 10,000,000,000ns vields diff of -17,000,000ns
9,974ms versus 10,000,001,118ns vields diff of -26,001,118ns
9,984ms versus 10,000,000,838ns vields diff of -16,000,838ns
9,973ms versus 10,000,001,117ns vields diff of -27,001,117ns
9,994ms versus 10,000,000,838ns vields diff of -6,000,838ns
9,973ms versus 10,000,000,559ns vields diff of -27,000,559ns
9,984ms versus 10,000,000,559ns vields diff of -16,000,559ns
9,973ms versus 10,000,001,118ns vields diff of -27,001,118ns
9,984ms versus 10,000,000,558ns vields diff of -16,000,558ns
9,973ms versus 10,000,000,000ns vields diff of -27,000,000ns
9,984ms versus 10,000,205,613ns vields diff of -16,205,613ns
9,973ms versus 10,000,000,280ns vields diff of -27,000,280ns
9,984ms versus 10,000,001,118ns vields diff of -16,001,118ns
[SNIP]
This demonstrates a couple of issues. First, you can see the impact of the ~10ms quanta of the system clock which seems indicate that the rate difference in the millisecond and nanosecond clock source is roughtly 0.16% - with the nanosecond clock running faster than the system clock.
That's on my notebook computer - your results will vary.