Perché ricevo un tempo trascorso negativo usando System.nanoTime ()?

Sto cercando di utilizzare il seguente codice con System.nanoTime() per misurare il tempo trascorso del codice.

 public static void main(String[] args) throws Exception { while (true) { long start = System.nanoTime(); for (int i = 0; i < 10000; i++) ; long end = System.nanoTime(); long cost = end - start; if (cost < 0) { System.out.println("start: " + start + ", end: " + end + ", cost: " + cost); } } } 

E ottengo questo risultato:

 start: 34571588742886, end: 34571585695366, cost: -3047520 start: 34571590239323, end: 34571586847711, cost: -3391612 start: 34571651240343, end: 34571648928369, cost: -2311974 start: 34571684937094, end: 34571681543134, cost: -3393960 start: 34571791867954, end: 34571788878081, cost: -2989873 start: 34571838733068, end: 34571835464021, cost: -3269047 start: 34571869993665, end: 34571866950949, cost: -3042716 start: 34571963747021, end: 34571960656216, cost: -3090805 start: 34571965020545, end: 34571961637608, cost: -3382937 start: 34572010616580, end: 34572007613257, cost: -3003323 

Perché ottengo valori negativi?

(SO: windows xp sp3, java: jdk1.6u27)

Il nanoTime può essere preso dal contatore del ciclo di clock della CPU. Dato che diverse CPU possono essere avviate in tempi leggermente diversi, il contatore di clock può essere diverso su diverse CPU. Linux lo corregge, ma le versioni precedenti di Windows no. (Suppongo tu abbia due CPU che sono state avviate a 3 ms di distanza)

Occasionalmente dovresti anche vedere salti positivi di oltre 2,5 ms.

Provare

 if (cost < 0 || cost > 2000000) { 

Dovresti vedere qualche salto in avanti e alcuni salti all’indietro mentre il processo passa da una CPU all’altra.