2011-10-23 14 views
15

Estoy tratando de usar el siguiente código con System.nanoTime() para medir el tiempo transcurrido del código.¿Por qué obtengo un tiempo transcurrido negativo usando System.nanoTime()?

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); 
     } 
    } 
} 

Y consigo como resultado:

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 

Por qué puedo obtener valores negativos?

(SO: Windows XP SP3, java: jdk1.6u27)

+4

no se puede reproducir en Linux con Java (TM) SE Runtime Environment (compilación 1.6.0_26-b03). De todos modos, ¿por qué te quejas? Cuando Java fue lento en la década de los noventa, la gente se quejó, ahora es * demasiado rápido *, y la gente aún se queja :-) – stivlo

+1

¿Se queja? Simplemente no puedo encontrar una forma correcta de medir el tiempo de ejecución del código. Nada que ver con rápido o lento. – Freewind

+2

relacionado: http://stackoverflow.com/questions/3274892/why-is-my-system-nanotime-broken – stivlo

Respuesta

14

El nanoTime se pueden tomar del contador de ciclos de reloj de la CPU. Como diferentes CPU pueden iniciarse en tiempos ligeramente diferentes, el contador de reloj puede ser diferente en diferentes CPU. Linux corrige esto, pero las versiones anteriores de Windows no lo hacen. (Supongo que tiene dos CPU que se iniciaron con 3 ms de separación)

También debería ver saltos positivos de más de 2,5 ms de vez en cuando.

Trate

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

Y hay que ver algunos salto hacia adelante y un poco de salto hacia atrás cuando se cambia el proceso entre las CPU.

+0

Tiene toda la razón. Nuevos resultados: -3494855, 4185715, -3562463, 3620073, 4175502, 3977789, -3500977, 4125248 – Freewind

+0

Esperaría que sea casi alternante. Donde hay un resultado positivo extra grande, el proceso podría detenerse y comenzar de nuevo en la misma CPU. –

Cuestiones relacionadas