tiempo restar medir horas ejecucion javascript profiling

javascript - restar - Cómo medir el tiempo que tarda una función en ejecutar.



medir tiempo de ejecucion en javascript (20)

Necesito obtener tiempo de ejecución en milisegundos.

Originalmente, formulé esta pregunta en 2008. La respuesta aceptada entonces fue usar la nueva Fecha (). GetTime () Sin embargo, todos podemos estar de acuerdo ahora en que usar la API de performance.now() estándar es más apropiado. Por lo tanto, estoy cambiando la respuesta aceptada a esta.


No use la fecha (). Lee abajo.

Utilice performance.now() :

<script> var a = performance.now(); alert(''do something...''); var b = performance.now(); alert(''It took '' + (b - a) + '' ms.''); </script>

Funciona en:

  • IE 10 ++

  • FireFox 15 ++

  • Cromo 24 ++

  • Safari 8 ++

  • Opera 15 ++

  • Android 4.4 ++

  • etcétera etcétera

console.time puede ser viable para usted , pero no es estándar § :

Esta característica no es estándar y no está en una pista estándar. No lo use en sitios de producción orientados a la Web: no funcionará para todos los usuarios. También puede haber grandes incompatibilidades entre las implementaciones y el comportamiento puede cambiar en el futuro.

Además de la compatibilidad con el navegador, performance.now parece tener el potencial de proporcionar tiempos más precisos, ya que parece ser la versión console.time de console.time .

<rant> Además, NUNCA use la Date para nada porque está afectada por cambios en la "hora del sistema". Lo que significa que obtendremos resultados no válidos, como "sincronización negativa", cuando el usuario no tenga una hora precisa del sistema:

En octubre de 2014, el reloj de mi sistema se volvió loco y adiviné qué ... Abrí Gmail y vi todos los correos electrónicos de mi día "enviados hace 0 minutos ". Y pensé que se supone que Gmail está construido por ingenieros de clase mundial de Google .......

(Establezca el reloj de su sistema hace un año y vaya a Gmail para que todos podamos reírnos. Quizás algún día tengamos un Salón de la Vergüenza para JS Date ).

La función now() Google Spreadsheet también tiene este problema.

La única vez que usará Date es cuando quiere mostrarle al usuario la hora del reloj de su sistema. No cuando quieres tener el tiempo o medir algo.


Utilizando performance.now() :

var t0 = performance.now(); doSomething(); // <---- The function you''re measuring time for var t1 = performance.now(); console.log("Call to doSomething took " + (t1 - t0) + " milliseconds.")

NodeJs : se requiere importar la clase de performance

Usando console.time : (no estándar)

console.time(''someFunction''); someFunction(); // Whatever is timed goes between the two "console.time" console.timeEnd(''someFunction'');

Nota :
La cadena que pasa a los métodos time() y timeEnd() debe coincidir
(para que el temporizador termine como se espera).

Documentación de console.time() :

  1. Documentación de NodeJS sobre
  2. Documentación MDN (lado del cliente)

¡La respuesta aceptada es incorrecta !

Dado que JavaScript es asíncrono, los valores de la variable final de la respuesta aceptada serían incorrectos.

var start = new Date().getTime(); for (i = 0; i < 50000; ++i) { // JavaScript is not waiting until the for is finished !! } var end = new Date().getTime(); var time = end - start; alert(''Execution time: '' + time);

La ejecución de for puede ser muy rápida, por lo que no puede ver que el resultado sea incorrecto. Puedes probarlo con un código haciendo alguna petición:

var start = new Date().getTime(); for (i = 0; i < 50000; ++i) { $.ajax({ url: ''www.oneOfYourWebsites.com'', success: function(){ console.log("success"); } }); } var end = new Date().getTime(); var time = end - start; alert(''Execution time: '' + time);

Por lo tanto, la alerta se activará rápidamente, pero en la consola verá que las solicitudes de ajax continúan.

Aquí está cómo debe hacerlo: performance.now()


Aquí hay un decorador para funciones de temporización.

let timed = (f) => (...args)=>{ let start = performance.now(); let ret = f(...args); console.log(`function ${f.name} took ${(performance.now()-start).toFixed(3)}ms`) return ret; }

Uso:

let test = ()=>{/*does something*/} test = timed(test) // turns the function into a timed function in one line test() // run your code as normal, logs ''function test took 1001.900ms''

Si está usando funciones asíncronas, puede hacer asíncronos timed y agregar una await antes de f (... args), y eso debería funcionar para ellos. Se vuelve más complicado si desea que un decorador maneje las funciones de sincronización y asíncrona.


Como se indicó anteriormente, compruebe y utilice el temporizador incorporado. Pero si quieres o necesitas escribir el tuyo, aquí están mis dos centavos:

//=-=|Source|=-=// /** * JavaScript Timer Object * * var now=timer[''elapsed''](); * timer[''stop''](); * timer[''start''](); * timer[''reset''](); * * @expose * @method timer * @return {number} */ timer=function(){ var a=Date.now(); b=0; return{ /** @expose */ elapsed:function(){return b=Date.now()-a}, start:function(){return a=Date.now()}, stop:function(){return Date.now()}, reset:function(){return a=0} } }(); //=-=|Google Advanced Optimized|=-=// timer=function(){var a=Date.now();b=0;return{a:function(){return b=Date.now()-a},start:function(){return a=Date.now()},stop:function(){return Date.now()},reset:function(){return a=0}}}();

La compilación fue un éxito!

  • Tamaño original: 219 bytes comprimidos (405 bytes sin comprimir)
  • Tamaño compilado: 109 bytes comprimidos (187 bytes sin comprimir)
  • Ahorro 50.23% del tamaño comprimido (53.83% sin gzip)

Dado que console.time y performance.now no son compatibles con algunos de los principales navegadores (es decir, IE10), creé una utilidad delgada que utiliza los mejores métodos disponibles. Sin embargo, carece de manejo de errores para usos falsos (llamar a End() en un temporizador no inicializado).

Úsalo y mejora como quieras.

Performance: { Timer: {}, Start: function (name) { if (console && console.time) { console.time(name); } else if (window.performance.now) { this.Timer[name] = window.performance.now(); } else { this.Timer[name] = new Date().getTime(); } }, End: function (name) { if (console && console.time) { console.timeEnd(name); } else { var result; if (window.performance.now) { result = window.performance.now() - this.Timer[name]; } else { result = new Date().getTime() - this.Timer[name]; } console.log(name + ": " + result); } } }


En mi caso, prefiero usar @ grammar suger y compilarlo con babel.
El problema de este método es que la función tiene que estar dentro del objeto.

Código JS de muestra

function timer() { return (target, propertyKey, descriptor) => { const start = Date.now(); let oldFunc = descriptor.value; descriptor.value = async function (){ var result = await oldFunc.apply(this, arguments); console.log(Date.now() - start); return result; } } } // Util function function delay(timeout) { return new Promise((resolve) => setTimeout(() => { resolve(); }, timeout)); } class Test { @timer() async test(timout) { await delay(timout) console.log("delay 1"); await delay(timout) console.log("delay 2"); } } const t = new Test(); t.test(1000) t.test(100)

.babelrc (para babel 6)

{ "plugins": [ "transform-decorators-legacy" ] }


Gracias, Achim Koellner, ampliará un poco tu respuesta:

var t0 = process.hrtime(); //Start of code to measure //End of code var timeInMilliseconds = process.hrtime(t0)[1]/1000000; // dividing by 1000000 gives milliseconds from nanoseconds

Tenga en cuenta que no debe hacer nada aparte de lo que desea medir (por ejemplo, console.log también tomará tiempo para ejecutarse y afectará las pruebas de rendimiento).

Tenga en cuenta que, en orden según el tiempo de ejecución de las funciones asíncronas, debe insertar var timeInMilliseconds = process.hrtime(t0)[1]/1000000; dentro de la devolución de llamada. Por ejemplo,

var t0 = process.hrtime(); someAsyncFunction(function(err, results) { var timeInMilliseconds = process.hrtime(t0)[1]/1000000; });


Hace un par de meses armé mi propia rutina que cronometra una función usando Date.now (), aunque en el momento el método aceptado parecía ser performance.now (), porque el objeto de rendimiento aún no está disponible (construido -in) en la versión estable de Node.js.

Hoy estaba investigando un poco más y encontré otro método para calcular el tiempo. Ya que también encontré cómo usar esto en el código de Node.js, pensé que lo compartiría aquí.

Lo siguiente se combina de los ejemplos dados por w3c y Node.js :

function functionTimer() { performance.mark(''start'') functionToBeTimed() performance.mark(''end'') performance.measure(''Start to End'', ''start'', ''end'') const measure = performance.getEntriesByName(''Start to End'')[0] console.log(measure.duration) }

NOTA:

Si pretende utilizar el objeto de performance en una aplicación Node.js, debe incluir el siguiente requisito: const { performance } = require(''perf_hooks'')


Para ampliar aún más el código de vsync y tener la capacidad de devolver el timeEnd como un valor en NodeJS, use este pequeño fragmento de código.

console.timeEndValue = function(label) { // Add console.timeEndValue, to add a return value var time = this._times[label]; if (!time) { throw new Error(''No such label: '' + label); } var duration = Date.now() - time; return duration; };

Ahora usa el código así:

console.time(''someFunction timer''); someFunction(); var executionTime = console.timeEndValue(''someFunction timer''); console.log("The execution time is " + executionTime);


Esto te da más posibilidades. Puede almacenar el tiempo de ejecución para usarlo con más propósitos, como usarlo en ecuaciones o almacenarlo en una base de datos, enviarlo a un cliente remoto a través de websockets, mostrarlo en una página web, etc.


Para obtener valores precisos debe utilizar la interfaz de rendimiento . Es compatible con las versiones modernas de Firefox, Chrome, Opera e IE. Aquí hay un ejemplo de cómo se puede usar:

var performance = window.performance; var t0 = performance.now(); doWork(); var t1 = performance.now(); console.log("Call to doWork took " + (t1 - t0) + " milliseconds.")

Date.getTime() o console.time() no son buenos para medir el tiempo de ejecución preciso. Puede usarlos si la estimación aproximada rápida está bien para usted. Por estimación aproximada quiero decir que puede obtener un cambio de 15 a 60 ms del tiempo real.

Compruebe esta brillante post sobre la medición del tiempo de ejecución en JavaScript. El autor también ofrece un par de enlaces sobre la precisión del tiempo de JavaScript, que vale la pena leer.


Puedes usar el operador add también aquí

var start = +new Date() for (i = 0; i < 50000; ++i) { // do something } var end = +new Date() var time = end - start; console.log(''total execution time = ''+ time + ''ms'');


Si desea medir el tiempo entre varias cosas que no están anidadas, puede usar esto:

function timer(lap){ if(lap) console.log(`${lap} in: ${(performance.now()-timer.prev).toFixed(3)}ms`); timer.prev = performance.now(); }

Similar a console.time (), pero más fácil de usar si no necesita realizar un seguimiento de los temporizadores anteriores.

Si te gusta el color azul de console.time (), puedes usar esta línea en su lugar

console.log(`${lap} in: %c${(performance.now()-timer.prev).toFixed(3)}ms`, ''color:blue'');

// Usage: timer() // set the start // do something timer(''built'') // logs ''built in: 591.815ms'' // do something timer(''copied'') // logs ''copied in: 0.065ms'' // do something timer(''compared'') // logs ''compared in: 36.41ms''


Te puede ayudar.

var t0 = date.now(); doSomething(); var t1 = date.now(); console.log("Call to doSomething took approximate" + (t1 - t0)/1000 + " seconds.")


Usa Firebug, habilita tanto la consola como Javascript. Haga clic en Perfil. Recargar. Haga clic en Perfil de nuevo. Ver el informe.


process.hrtime () está disponible dentro de Node.js ; devuelve un valor en nanosegundos

var hrTime = process.hrtime() console.log(hrTime[0] * 1000000 + hrTime[1] / 1000)


usar nueva fecha (). getTime ()

El método getTime () devuelve el número de milisegundos desde la medianoche del 1 de enero de 1970.

ex.

var start = new Date().getTime(); for (i = 0; i < 50000; ++i) { // do something } var end = new Date().getTime(); var time = end - start; alert(''Execution time: '' + time);


Si necesita obtener el tiempo de ejecución de la función en su máquina de desarrollo local , puede usar las herramientas de creación de perfiles de su navegador, o comandos de console.time() como console.time() y console.timeEnd() .

Todos los navegadores modernos tienen perfiladores de JavaScript incorporados. Estos perfiladores deben proporcionar la medida más precisa, ya que no tiene que modificar su código existente, lo que podría afectar el tiempo de ejecución de la función.

Para perfilar su JavaScript:

  • En Chrome , presione F12 y seleccione la pestaña Perfiles , luego Recoja el perfil de CPU de JavaScript .
  • En Firefox , instale / abra Firebug y haga clic en el botón Perfil .
  • En IE 9+ , presione F12 , haga clic en Script o Profiler (dependiendo de su versión de IE).

Alternativamente, en su máquina de desarrollo , puede agregar instrumentación a su código con console.time() y console.timeEnd() . Estas funciones, compatibles con Firefox11 +, Chrome2 + e IE11 +, informan sobre los temporizadores que inicia / detiene a través de console.time() . time() toma un nombre de temporizador definido por el usuario como un argumento, y timeEnd() luego informa sobre el tiempo de ejecución desde que se inició el temporizador:

function a() { console.time("mytimer"); ... do stuff ... var dur = console.timeEnd("myTimer"); // NOTE: dur only works in FF }

Tenga en cuenta que solo Firefox devuelve el tiempo transcurrido en la llamada timeEnd() . Los otros navegadores simplemente informan el resultado a la consola del desarrollador: el valor de retorno de timeEnd() no está definido.

Si desea obtener el tiempo de ejecución de la función en libertad , deberá instrumentar su código. Usted tiene un par de opciones. Simplemente puede guardar las horas de inicio y finalización consultando la new Date().getTime() :

function a() { var start = new Date().getTime(); ... do stuff ... var end = new Date().getTime(); var dur = end - start; }

Sin embargo, el objeto Date solo tiene una resolución de milisegundos y se verá afectado por los cambios en el reloj del sistema de cualquier SO. En los navegadores modernos, hay una mejor opción.

La mejor opción es usar el Tiempo de alta resolución , también window.performance.now() como window.performance.now() . now() es mejor que el Date.getTime() tradicional en dos formas importantes:

  1. 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).

  2. now() está aumentando monótonamente. Esto es importante ya que Date.getTime() posiblemente puede saltar hacia adelante o incluso hacia atrás en llamadas subsiguientes. En particular, si se actualiza la hora del sistema operativo (por ejemplo, la sincronización del reloj atómico), Date.getTime() también se actualiza. now() se garantiza que siempre aumentará monótonamente, por lo que no se ve afectado por la hora 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 que son la new Date().getTime() , + new Date y la Date.now() . La excepción es que Date y now() veces no se mezclan, ya que Date se basa en unix-epoch (el número de milisegundos desde 1970), mientras que now() es el número de milisegundos desde que comenzó la navegación de la página (por lo que Ser mucho más pequeño que la Date ).

Aquí hay un ejemplo de cómo usar now() :

function a() { var start = window.performance.now(); ... do stuff ... var end = window.performance.now(); var dur = end - start; }

now() es compatible con Chrome stable, Firefox 15+ e IE10. También hay varios polyfills disponibles.

Otra opción para medir el tiempo de ejecución en la naturaleza es UserTiming . UserTiming se comporta de forma similar a console.time() y console.timeEnd() , pero utiliza la misma marca de tiempo de alta resolución que now() usa (para que obtenga un reloj monótonamente sub-milisegundo), y guarda las marcas de tiempo y duraciones para el PerformanceTimeline .

UserTiming tiene los conceptos de marcas ( marcas de tiempo) y medidas (duraciones). Puede definir tantos como desee, y se exponen en PerformanceTimeline .

Para guardar una marca de tiempo, llame a mark(startMarkName) . Para obtener la duración desde su primera marca, simplemente llame a measure(measurename, startMarkname) . La duración se guarda en PerformanceTimeline junto con sus marcas.

function a() { window.performance.mark("start"); ... do stuff ... window.performance.measure("myfunctionduration", "start"); } // duration is window.performance.getEntriesByName("myfunctionduration", "measure")[0];

UserTiming está disponible en IE10 + y Chrome25 +. También hay un polyfill disponible (que escribí).


export default class Singleton { static myInstance: Singleton = null; _timers: any = {}; /** * @returns {Singleton} */ static getInstance() { if (Singleton.myInstance == null) { Singleton.myInstance = new Singleton(); } return this.myInstance; } initTime(label: string) { this._timers[label] = Date.now(); return this._timers[label]; } endTime(label: string) { const endTime = Date.now(); if (this._timers[label]) { const delta = endTime - this._timers[label]; const finalTime = `${label}: ${delta}ms`; delete this._timers[label]; return finalTime; } else { return null; } } }

InitTime relacionado con la string .

return Singleton.getInstance().initTime(label); // Returns the time init

return Singleton.getInstance().endTime(label); // Returns the total time between init and end


var StopWatch = function (performance) { this.startTime = 0; this.stopTime = 0; this.running = false; this.performance = performance === false ? false : !!window.performance; }; StopWatch.prototype.currentTime = function () { return this.performance ? window.performance.now() : new Date().getTime(); }; StopWatch.prototype.start = function () { this.startTime = this.currentTime(); this.running = true; }; StopWatch.prototype.stop = function () { this.stopTime = this.currentTime(); this.running = false; }; StopWatch.prototype.getElapsedMilliseconds = function () { if (this.running) { this.stopTime = this.currentTime(); } return this.stopTime - this.startTime; }; StopWatch.prototype.getElapsedSeconds = function () { return this.getElapsedMilliseconds() / 1000; }; StopWatch.prototype.printElapsed = function (name) { var currentName = name || ''Elapsed:''; console.log(currentName, ''['' + this.getElapsedMilliseconds() + ''ms]'', ''['' + this.getElapsedSeconds() + ''s]''); };

Punto de referencia

var stopwatch = new StopWatch(); stopwatch.start(); for (var index = 0; index < 100; index++) { stopwatch.printElapsed(''Instance['' + index + '']''); } stopwatch.stop(); stopwatch.printElapsed();

Salida

Instance[0] [0ms] [0s] Instance[1] [2.999999967869371ms] [0.002999999967869371s] Instance[2] [2.999999967869371ms] [0.002999999967869371s] /* ... */ Instance[99] [10.999999998603016ms] [0.010999999998603016s] Elapsed: [10.999999998603016ms] [0.010999999998603016s]

performance.now() es opcional; simplemente pase falso a la función de constructor de StopWatch.