¿Hay funciones de sincronización en JavaScript con resolución de microsegundos?
Soy consciente de timer.js para Chrome y espero que haya una solución para otros navegadores amigables, como Firefox, Safari, Opera, Epiphany, Konqueror, etc. No estoy interesado en admitir ningún IE, pero las respuestas incluyen IE son bienvenidos.
(Dada la poca precisión de la sincronización de milisegundos en JS, ¡no estoy conteniendo la respiración en este caso!)
Actualización: timer.js anuncia una resolución de microsegundos, pero simplemente multiplica la lectura de milisegundos por 1,000. Verificado mediante pruebas e inspección de código. Decepcionado. : [
javascript
mwcz
fuente
fuente
Respuestas:
Como se menciona en la respuesta de Mark Rejhon, hay una API disponible en los navegadores modernos que expone datos de tiempo de resolución de menos de milisegundos al script: el temporizador de alta resolución W3C , también conocido como
window.performance.now()
.now()
es mejor que el tradicionalDate.getTime()
de dos formas importantes:now()
es un doble con resolución de submilisegundos que representa el número de milisegundos desde el inicio de la navegación de la página. Devuelve el número de microsegundos en la fracción (por ejemplo, un valor de 1000,123 es 1 segundo y 123 microsegundos).now()
está aumentando monótonamente. Esto es importante yaDate.getTime()
que posiblemente puede avanzar o incluso retroceder en llamadas posteriores. En particular, si se actualiza la hora del sistema del sistema operativo (por ejemplo, sincronización del reloj atómico),Date.getTime()
también se actualiza.now()
se garantiza que siempre aumentará de manera monótona, por lo que no se verá afectado por la hora del sistema del sistema operativo; siempre será la hora del reloj de pared (suponiendo que su reloj de pared no sea atómico ...).now()
se puede utilizar en casi todos los lugares quenew Date.getTime()
,+ new Date
yDate.now()
están. La excepción es queDate
y losnow()
tiempos no se mezclan, ya queDate
se basa en unix-epoch (el número de milisegundos desde 1970), mientras quenow()
es el número de milisegundos desde que comenzó la navegación de la página (por lo que será mucho menor queDate
).now()
es compatible con Chrome estable, Firefox 15+ e IE10. También hay varios polyfills disponibles.fuente
new Date.getTime()
no es una cosa.new Date().getTime()
es.console.log
en cada ejecución) Es difícil de entender, pero copie todo el código resaltado aquí:last=-11; same=0; runs=100; for(let i=0;i<runs;i++) { let now = performance.now(); console.log('.'); if (now === last) { same++; } last = now; } console.log(same, 'were the same');
Ahora hay un nuevo método para medir microsegundos en javascript: http://gent.ilcore.com/2012/06/better-timer-for-javascript.html
Sin embargo, en el pasado, encontré un método tosco para obtener una precisión de 0.1 milisegundos en JavaScript con un temporizador de milisegundos. ¿Imposible? No Sigue leyendo:
Estoy haciendo algunos experimentos de alta precisión que requieren precisiones de temporizador autoverificadas, y descubrí que pude obtener de manera confiable una precisión de 0.1 milisegundos con ciertos navegadores en ciertos sistemas.
He descubierto que en los navegadores web modernos acelerados por GPU en sistemas rápidos (por ejemplo, i7 de cuatro núcleos, donde varios núcleos están inactivos, solo ventana del navegador), ahora puedo confiar en que los temporizadores tienen una precisión de milisegundos. De hecho, se ha vuelto tan preciso en un sistema i7 inactivo que he podido obtener de manera confiable exactamente el mismo milisegundo, en más de 1,000 intentos. Solo cuando intento hacer cosas como cargar una página web adicional u otra, la precisión de milisegundos se degrada (y puedo detectar con éxito mi propia precisión degradada haciendo una verificación de tiempo antes y después, para ver si mi tiempo de procesamiento se alargó repentinamente a 1 o más milisegundos; esto me ayuda a invalidar los resultados que probablemente se hayan visto afectados demasiado negativamente por las fluctuaciones de la CPU).
Se ha vuelto tan preciso en algunos navegadores acelerados por GPU en sistemas i7 de cuatro núcleos (cuando la ventana del navegador es la única ventana), que descubrí que deseaba poder acceder a un temporizador de precisión de 0.1ms en JavaScript, ya que la precisión finalmente es ahora existen en algunos sistemas de navegación de alta gama para hacer que la precisión del temporizador valga la pena para ciertos tipos de aplicaciones de nicho que requieren alta precisión, y donde las aplicaciones pueden autoverificarse para detectar desviaciones de precisión.
Obviamente, si está haciendo varias pasadas, simplemente puede ejecutar varias pasadas (por ejemplo, 10 pasadas) y luego dividir por 10 para obtener una precisión de 0,1 milisegundos. Ese es un método común para obtener una mejor precisión: realice varias pasadas y divida el tiempo total por la cantidad de pasadas.
SIN EMBARGO ... Si solo puedo hacer una única prueba comparativa de una prueba específica debido a una situación inusualmente única, descubrí que puedo obtener una precisión de 0.1 (y a veces 0.01ms) al hacer esto:
Inicialización / Calibración:
Evaluación comparativa de una pasada con precisión de menos de milisegundos:
ADVERTENCIA: NO se recomiendan los bucles ocupados en los navegadores web, pero, afortunadamente, estos bucles ocupados se ejecutan durante menos de 1 milisegundo cada uno y solo se ejecutan unas pocas veces.
Las variables como la compilación JIT y las fluctuaciones de la CPU agregan inexactitudes masivas, pero si ejecuta varias pasadas de inicialización, tendrá una recompilación dinámica completa y, finalmente, el contador se asentará en algo muy preciso. Asegúrese de que todos los bucles ocupados tengan exactamente la misma función para todos los casos, de modo que las diferencias en los bucles ocupados no den lugar a diferencias. Asegúrese de que todas las líneas de código se ejecuten varias veces antes de comenzar a confiar en los resultados, para permitir que los compiladores JIT ya se hayan estabilizado en una recompilación dinámica completa (dynarec).
De hecho, fui testigo de la precisión acercándose a los microsegundos en ciertos sistemas, pero todavía no me fiaría de ella. Pero la precisión de 0,1 milisegundos parece funcionar de manera bastante confiable, en un sistema de cuatro núcleos inactivo donde soy la única página del navegador. Llegué a un caso de prueba científica en el que solo podía hacer pases únicos (debido a que se producían variables únicas), y necesitaba cronometrar con precisión cada pase, en lugar de promediar múltiples pases repetidos, por eso hice esto.
Hice varios pases previos y pases ficticios (también para ajustar el dynarec), para verificar la confiabilidad de la precisión de 0,1 ms (permaneció sólido durante varios segundos), luego mantuve mis manos fuera del teclado / mouse, mientras se realizaba el punto de referencia, luego hice varios pasadas posteriores para verificar la confiabilidad de una precisión de 0,1 ms (se mantuvo sólido nuevamente). Esto también verifica que cosas como cambios de estado de energía u otras cosas, no ocurrieron entre el antes y el después, lo que interfiere con los resultados. Repita la prueba previa y la prueba posterior entre cada pasada de referencia. Sobre esto, estaba prácticamente seguro de que los resultados intermedios eran precisos. No hay garantía, por supuesto, pero demuestra que en algunos casos es posible una precisión de <0,1 ms en un navegador web.
Este método solo es útil en casos muy específicos . Aun así, literalmente no será 100% infinitamente garantizado, puede obtener una precisión bastante confiable e incluso una precisión científica cuando se combina con varias capas de verificaciones internas y externas.
fuente
Date.now()
o+new Date()
. Pero ahora tenemosperformance.now()
. Si bien está claro que ha encontrado algunas formas geniales de piratear más capacidades, esta respuesta es esencialmente obsoleta. Además, no recomiende nada relacionado con bucles ocupados. Simplemente no hagas eso. No necesitamos más de eso.La respuesta es "no", en general. Si está utilizando JavaScript en algún entorno del lado del servidor (es decir, no en un navegador), entonces todas las apuestas están canceladas y puede intentar hacer lo que quiera.
editar - esta respuesta es antigua; los estándares han progresado y hay nuevas instalaciones disponibles como soluciones al problema de la hora exacta. Aun así, debe recordarse que fuera del dominio de un verdadero sistema operativo en tiempo real, el código ordinario sin privilegios tiene un control limitado sobre su acceso a los recursos informáticos. Medir el rendimiento no es lo mismo (necesariamente) que predecir el rendimiento.
fuente
Aquí hay un ejemplo que muestra mi temporizador de alta resolución para node.js :
Uso:
Normalmente, es posible que pueda utilizar:
Si está cronometrando secciones de código que implican bucles, no puede obtener acceso al valor de
console.timeEnd()
para sumar los resultados del temporizador. Puede, pero se pone desagradable porque tiene que inyectar el valor de su variable iterativa, comoi
, y establecer una condición para detectar si el ciclo está terminado.Aquí tienes un ejemplo porque puede ser útil:
Citar: https://nodejs.org/api/process.html#process_process_hrtime_time
fuente