Yo y otro desarrollador recientemente pasé de una máquina Core 2 Duo en el trabajo a una nueva Core 2 Quad 9505; ambos ejecutando Windows XP SP3 de 32 bits con JDK 1.6.0_18.¿Por qué se rompe mi System.nanoTime()?
Al hacerlo, un par de nuestras pruebas unitarias automatizadas para algún código de agregación de temporización/estadísticas/métricas comenzaron a fallar rápidamente, debido a lo que parecen ser valores ridículos que vuelven de System.nanoTime().
Código de ensayo que muestra este comportamiento, de forma fiable, en mi máquina es:
import static org.junit.Assert.assertThat;
import org.hamcrest.Matchers;
import org.junit.Test;
public class NanoTest {
@Test
public void testNanoTime() throws InterruptedException {
final long sleepMillis = 5000;
long nanosBefore = System.nanoTime();
long millisBefore = System.currentTimeMillis();
Thread.sleep(sleepMillis);
long nanosTaken = System.nanoTime() - nanosBefore;
long millisTaken = System.currentTimeMillis() - millisBefore;
System.out.println("nanosTaken="+nanosTaken);
System.out.println("millisTaken="+millisTaken);
// Check it slept within 10% of requested time
assertThat((double)millisTaken, Matchers.closeTo(sleepMillis, sleepMillis * 0.1));
assertThat((double)nanosTaken, Matchers.closeTo(sleepMillis * 1000000, sleepMillis * 1000000 * 0.1));
}
}
salida típica:
millisTaken=5001
nanosTaken=2243785148
Ejecutarlo rendimientos 100x resultados nano entre 33% y 60% de la actual hora de dormir; generalmente alrededor del 40% sin embargo.
Entiendo las debilidades en la precisión de los temporizadores en Windows, y he leído hilos relacionados como Is System.nanoTime() consistent across threads?, sin embargo entiendo que System.nanoTime() está destinado exactamente para el propósito que lo estamos usando: - medir el tiempo transcurrido; más exactamente que currentTimeMillis().
¿Alguien sabe por qué está devolviendo resultados tan locos? ¿Es probable que esto sea un problema de arquitectura de hardware (la única cosa importante que ha cambiado es la CPU/placa base en esta máquina)? ¿Un problema con Windows HAL con mi hardware actual? Un problema JDK? ¿Debo abandonar nanoTime()? ¿Debo registrar un error en algún lugar, o alguna sugerencia sobre cómo puedo investigar más?
ACTUALIZACIÓN 19/07 03:15 UTC: Después de intentar caso de prueba de finnw continuación he hecho un poco más buscando en Google, al encontrarse con entradas como bugid:6440250. También me recordó a algún otro comportamiento extraño que noté la noche del viernes, donde los pings regresaban negativos. Así que agregué /usepmtimer a mi boot.ini y ahora todas las pruebas se comportan como se esperaba. Y mis pings también son normales.
Estoy un poco confundido acerca de por qué esto todavía era un problema; de mi lectura pensé que los problemas de TSC vs PMT se resolvieron en gran medida en Windows XP SP3. ¿Podría ser porque mi máquina era originalmente SP2 y se parchó en SP3 en lugar de instalarse originalmente como SP3? Ahora también me pregunto si debería instalar parches como el del MS KB896256. ¿Quizás debería abordar esto con el equipo corporativo de construcción de escritorios?
¿Obtuvo una máquina completamente nueva o su máquina actual se actualizó manteniendo la antigua instalación de Windows? –
Máquina completamente nueva; reconstruido en una construcción estándar corporativa. – Chad
funciona bien para mí en Windows 7 64 bit último JDK 6. – TofuBeer