¿Cómo se prueba el rendimiento del código JavaScript?

337

Ciclos de CPU, uso de memoria, tiempo de ejecución, etc.

Agregado: ¿Existe una forma cuantitativa de probar el rendimiento en JavaScript además de la percepción de la rapidez con que se ejecuta el código?

danmine
fuente
Es posible que desee ver el complemento YSlow para Firefox.
Rob Wells
77
Eso solo te dirá cuánto tiempo lleva cargar. Creo que la pregunta estaba más relacionada con el rendimiento cuando se está ejecutando.
Sam Hasler
Si desea instrumentar su código para el rendimiento de la manera más común (y más precisa ya que puede perfeccionar funciones específicas). Esta publicación tiene un ejemplo decente del uso de un temporizador (pero realmente debería mirar Performance.now si tiene la oportunidad): albertech.blogspot.com/2015/07/…
jar
1
Para las pruebas rápidas y sencillas en su navegador se puede utilizar jsben.ch
EscapeNetscape

Respuestas:

325

Los perfiladores son definitivamente una buena manera de obtener números, pero en mi experiencia, el rendimiento percibido es todo lo que le importa al usuario / cliente. Por ejemplo, tuvimos un proyecto con un acordeón Ext que se expandió para mostrar algunos datos y luego algunas cuadrículas Ext anidadas. En realidad, todo se estaba procesando bastante rápido, ninguna operación sola tomó mucho tiempo, solo se procesó mucha información a la vez, por lo que el usuario se sintió lento.

"Arreglamos" esto, no cambiando a un componente más rápido u optimizando algún método, sino representando primero los datos y luego representando las cuadrículas con setTimeout. Entonces, la información apareció primero, luego las cuadrículas aparecerían en su lugar un segundo después. En general, tomó un poco más de tiempo de procesamiento hacerlo de esa manera, pero para el usuario, el rendimiento percibido mejoró.


En estos días, el perfilador Chrome y otras herramientas son universalmente disponibles y fáciles de usar, como son console.time(), console.profile()y performance.now(). Chrome también le brinda una vista de línea de tiempo que puede mostrarle qué está matando su velocidad de cuadros, dónde podría estar esperando el usuario, etc.

Encontrar documentación para todas estas herramientas es realmente fácil, no necesita una respuesta SO para eso. 7 años después, seguiré repitiendo el consejo de mi respuesta original y señalaré que puede ejecutar código lento para siempre donde un usuario no lo notará, y ejecutar código bastante rápido donde lo hace, y se quejarán sobre el el código bastante rápido no es lo suficientemente rápido. O que su solicitud a la API de su servidor tomó 220 ms. O algo más como eso. El punto sigue siendo que si saca un generador de perfiles y busca trabajo que hacer, lo encontrará, pero puede que no sea el trabajo que necesitan sus usuarios.

Noé
fuente
3
Es un paso de ajuste fino después de que los conocidos algoritmos de buen rendimiento estén en su lugar.
Rafael Xavier
1
Esta es una muy buena respuesta, ya que toma un enfoque práctico para la mayoría de las situaciones que describe la pregunta. Sin embargo, no responde la pregunta , que es preguntar si hay otra forma de medir esto además de la percepción del usuario. El tiempo de inactividad completo, como cuando los botones están congelados, aún se puede medir utilizando los métodos en la respuesta de pramodc y los comentarios adjuntos.
RoboticRenaissance
202

Estoy de acuerdo en que el rendimiento percibido es realmente todo lo que importa. Pero a veces solo quiero averiguar qué método de hacer algo es más rápido. A veces la diferencia es ENORME y vale la pena conocerla.

Podrías simplemente usar temporizadores de JavaScript. Pero típicamente obtengo resultados mucho más consistentes usando los métodos devTool console.time()y Chrome nativos de Chrome (ahora también en Firefox y Safari)console.timeEnd()

Ejemplo de cómo lo uso:

var iterations = 1000000;
console.time('Function #1');
for(var i = 0; i < iterations; i++ ){
    functionOne();
};
console.timeEnd('Function #1')

console.time('Function #2');
for(var i = 0; i < iterations; i++ ){
    functionTwo();
};
console.timeEnd('Function #2')

Los resultados se ven así

Actualización (4/4/2016):

Chrome canary agregó recientemente el perfil de nivel de línea en la pestaña de fuentes de herramientas de desarrollo que le permite ver exactamente cuánto tiempo tardó en ejecutarse cada línea. ingrese la descripción de la imagen aquí

Jose Browne
fuente
Sí, uno de los encantos con este es que es rápido y fácil de implementar. Me pregunto si el registro per se tomará parte del rendimiento de la ejecución de JavaScript. Digamos que tenemos un bucle en un juego y genera múltiples filas de registros. Por ejemplo, una vez por segundo durante 5 minutos, es decir, 300 filas. ¿Alguien sabe?
K. Kilian Lindberg
¿Sigue siendo operativo? No aparece en Chrome.
Estadísticas de aprendizaje con el ejemplo del
2
Sí, todavía funciona para mí. developer.chrome.com/devtools/docs/console-api#consoletimelabel
Jose Browne
@ K.KilianLindberg El registro siempre tomará tiempo del rendimiento, al igual que cualquier código, pero a) será coherente en sus pruebas yb) no debe iniciar sesión en la consola en el código en vivo. Después de probar en mi máquina, el registro de tiempo es solo una fracción de una MS, pero se sumará cuanto más lo hagas.
Polyducks
92

Siempre podemos medir el tiempo que toma cualquier función mediante un simple objeto de fecha .

var start = +new Date();  // log start timestamp
function1();
var end =  +new Date();  // log end timestamp
var diff = end - start;
pramodc84
fuente
10
Tenga en cuenta que esta solución devuelve la diferencia en milisegundos
Chris Bier
16
Se desaconseja el uso de Date () ya que el tiempo en milisegundos puede variar según los factores del sistema. En su lugar, use console.time () y console.timeEnd (). Vea la respuesta de JQuery Lover para más detalles.
mbokil
44
Aún mejor, useperformance.now()
edan
1
Antes de usar performance.now (), verifique la compatibilidad del navegador. developer.mozilla.org/en-US/docs/Web/API/Performance/…
AR_HZ
La fecha no es realmente representativa del tiempo transcurrido. Echa un vistazo a este artículo: sitepoint.com/measuring-javascript-functions-performance . Performance.now () es una marca de tiempo más precisa.
Millsionaire
61

Prueba jsPerf . Es una herramienta de rendimiento de JavaScript en línea para comparar y comparar fragmentos de código. Lo uso todo el tiempo.

Relajarse
fuente
1
Como jsPerf no funciona en este momento , benchmarkjs es fácil de usar .
mucaho
También lo recomiendo ya que da una medición de operaciones / seg (ejecuta su código varias veces)
Richard
+9001 (eso es más de nueve mil;) para jsPerf. Regularmente uso esto de manera similar a %timeiten un ipythonshell REPL para código Python.
amcgregor
37

La mayoría de los navegadores ahora están implementando el tiempo de alta resolución performance.now(). Es superior a new Date()las pruebas de rendimiento porque funciona independientemente del reloj del sistema.

Uso

var start = performance.now();

// code being timed...

var duration = performance.now() - start;

Referencias

Daniel Imms
fuente
2
Aún mejor sería usar la API de sincronización de usuario , que se basa en performance.now().
Chris
30

JSLitmus es una herramienta ligera para crear pruebas de referencia JavaScript ad-hoc

Vamos a examinar el rendimiento entre function expressiony function constructor:

<script src="JSLitmus.js"></script>
<script>

JSLitmus.test("new Function ... ", function() { 
    return new Function("for(var i=0; i<100; i++) {}"); 
});

JSLitmus.test("function() ...", function() { 
       return (function() { for(var i=0; i<100; i++) {}  });
});

</script>

Lo que hice arriba es crear una function expressiony function constructorrealizar la misma operación. El resultado es el siguiente:

Resultado de rendimiento de FireFox

Resultado de rendimiento de FireFox

Resultado de rendimiento de IE

Resultado de rendimiento de IE

Ramiz Uddin
fuente
La página vinculada de JSLitmus contiene enlaces de descarga rotos. He encontrado JSLitmus (para navegadores) y jslitmus (para NodeJS, en minúsculas).
Rob W
16

Algunas personas sugieren complementos y / o navegadores específicos. No lo haría porque solo son realmente útiles para esa plataforma; una prueba ejecutada en Firefox no se traducirá con precisión a IE7. Teniendo en cuenta que el 99.999999% de los sitios tienen más de un navegador que los visita, debe verificar el rendimiento en todas las plataformas populares.

Mi sugerencia sería mantener esto en el JS. Cree una página de evaluación comparativa con todas sus pruebas de JS y programe la ejecución. Incluso podría hacer que AJAX publique los resultados para mantenerlo completamente automatizado.

Luego solo enjuague y repita sobre diferentes plataformas.

Oli
fuente
55
Esto es cierto, pero los perfiladores son buenos en caso de que haya un problema de codificación que no tenga nada que ver con un problema específico del navegador.
John Boker
1
¡Por supuesto! Sí, detectarán problemas generales de "codificación incorrecta" y los específicos son excelentes para realizar la depuración real, pero para las pruebas de casos de uso generales, se beneficiará de algo que se ejecuta en todas las plataformas.
Oli
2
+1 en la nota de que esto es cierto, pero tener un generador de perfiles como Firebug sigue siendo genial, si no esencial, para encontrar cuellos de botella.
Pekka
1
" Considerando el 99.999999% de los sitios ... " Creo que lo inventó ...: - /
RobG
@RobG Podría estar exagerando un decimal o dos, pero la idea de que su plataforma de desarrollo probablemente no será idéntica a su plataforma de implementación.
Oli
11

Tengo una pequeña herramienta donde puedo ejecutar rápidamente pequeños casos de prueba en el navegador e inmediatamente obtener los resultados:

Prueba de velocidad de JavaScript

Puedes jugar con el código y descubrir qué técnica es mejor en el navegador probado.

DUzun
fuente
Gracias, esto es justo lo que estaba buscando.
Joseph Sheedy
9

Aquí hay una función simple que muestra el tiempo de ejecución de una función pasada:

var perf = function(testName, fn) {
    var startTime = new Date().getTime();
    fn();
    var endTime = new Date().getTime();
    console.log(testName + ": " + (endTime - startTime) + "ms");
}
Bunz
fuente
4

Respuesta rápida

En jQuery (más específicamente en Sizzle), usamos esto (checkout master y open speed / index.html en su navegador), que a su vez usa benchmark.js . Esto se utiliza para probar el rendimiento de la biblioteca.

Respuesta larga

Si el lector no conoce la diferencia entre el punto de referencia, la carga de trabajo y los perfiladores, primero lea algunos fundamentos de las pruebas de rendimiento en la sección "readme 1st" de spec.org . Esto es para las pruebas del sistema, pero comprender estos fundamentos también ayudará a las pruebas JS perf. Algunos puntos destacados:

¿Qué es un punto de referencia?

Un punto de referencia es "un estándar de medición o evaluación" (Diccionario Webster's II). Un punto de referencia informático suele ser un programa informático que realiza un conjunto de operaciones estrictamente definido, una carga de trabajo, y devuelve alguna forma de resultado, una métrica, que describe cómo se desempeñó la computadora probada. Las métricas de referencia de la computadora generalmente miden la velocidad: qué tan rápido se completó la carga de trabajo; o rendimiento: cuántas unidades de carga de trabajo por unidad de tiempo se completaron. Ejecutar el mismo punto de referencia de computadora en varias computadoras permite hacer una comparación.

¿Debo comparar mi propia aplicación?

Idealmente, la mejor prueba de comparación para sistemas sería su propia aplicación con su propia carga de trabajo. Desafortunadamente, a menudo no es práctico obtener una amplia base de mediciones confiables, repetibles y comparables para diferentes sistemas utilizando su propia aplicación con su propia carga de trabajo. Los problemas pueden incluir la generación de un buen caso de prueba, problemas de confidencialidad, dificultad para garantizar condiciones comparables, tiempo, dinero u otras restricciones.

Si no es mi propia aplicación, ¿entonces qué?

Es posible que desee considerar el uso de puntos de referencia estandarizados como punto de referencia. Idealmente, un punto de referencia estandarizado será portátil y puede que ya se haya ejecutado en las plataformas que le interesan. Sin embargo, antes de considerar los resultados, debe asegurarse de comprender la correlación entre sus necesidades de aplicación / computación y cuáles son El punto de referencia está midiendo. ¿Son los puntos de referencia similares a los tipos de aplicaciones que ejecuta? ¿Las cargas de trabajo tienen características similares? Según sus respuestas a estas preguntas, puede comenzar a ver cómo el punto de referencia puede aproximarse a su realidad.

Nota: Un punto de referencia estandarizado puede servir como punto de referencia. Sin embargo, cuando realiza una selección de proveedor o producto, SPEC no afirma que ningún punto de referencia estandarizado pueda reemplazar la evaluación comparativa de su propia aplicación real.

Pruebas de rendimiento JS

Idealmente, la mejor prueba de rendimiento sería usar su propia aplicación con su propia carga de trabajo cambiando lo que necesita probar: diferentes bibliotecas, máquinas, etc.

Si esto no es factible (y generalmente no lo es). El primer paso importante: define tu carga de trabajo. Debe reflejar la carga de trabajo de su aplicación. En esta charla , Vyacheslav Egorov habla sobre cargas de trabajo de mierda que debes evitar.

Luego, puede usar herramientas como benchmark.js para ayudarlo a recopilar métricas, generalmente la velocidad o el rendimiento. En Sizzle, estamos interesados ​​en comparar cómo las correcciones o cambios afectan el rendimiento sistémico de la biblioteca.

Si algo funciona realmente mal, su próximo paso es buscar cuellos de botella.

¿Cómo encuentro cuellos de botella? Perfiladores

¿Cuál es la mejor manera de perfilar la ejecución de JavaScript?

Rafael Xavier
fuente
3

Creo que el tiempo de ejecución es la mejor medida.

pdavis
fuente
¿A diferencia de qué? No estoy seguro de entender.
Pekka
A diferencia de la pregunta original de los carteles: "Ciclos de CPU, uso de memoria, tiempo de ejecución, etc.?"
risita
2

Por lo general, solo pruebo el rendimiento de JavaScript, cuánto tiempo se ejecuta el script. jQuery Lover dio un buen enlace de artículo para probar el rendimiento del código de JavaScript , pero el artículo solo muestra cómo probar cuánto tiempo se ejecuta su código de JavaScript. También recomendaría leer el artículo llamado "5 consejos para mejorar su código jQuery mientras trabaja con grandes conjuntos de datos".

Uzbekjon
fuente
2

Aquí hay una clase reutilizable para el rendimiento del tiempo. El ejemplo está incluido en el código:

/*
     Help track time lapse - tells you the time difference between each "check()" and since the "start()"

 */
var TimeCapture = function () {
    var start = new Date().getTime();
    var last = start;
    var now = start;
    this.start = function () {
        start = new Date().getTime();
    };
    this.check = function (message) {
        now = (new Date().getTime());
        console.log(message, 'START:', now - start, 'LAST:', now - last);
        last = now;
    };
};

//Example:
var time = new TimeCapture();
//begin tracking time
time.start();
//...do stuff
time.check('say something here')//look at your console for output
//..do more stuff
time.check('say something else')//look at your console for output
//..do more stuff
time.check('say something else one more time')//look at your console for output
Shawn Dotey
fuente
1

UX Profiler aborda este problema desde la perspectiva del usuario. Agrupa todos los eventos del navegador, la actividad de la red, etc. causados ​​por alguna acción del usuario (clic) y tiene en cuenta todos los aspectos como la latencia, los tiempos de espera, etc.

Konstantin Triger
fuente
1

Estaba buscando algo similar pero encontré esto.

https://jsbench.me/

Permite una comparación de lado a lado y luego también puede compartir los resultados.

Ste
fuente
0

La regla de oro es NO bloquear bajo ninguna circunstancia el navegador de su usuario. Después de eso, generalmente miro el tiempo de ejecución, seguido del uso de memoria (a menos que esté haciendo algo loco, en cuyo caso podría ser una prioridad más alta).

William Keller
fuente
0

Las pruebas de rendimiento se convirtieron en una palabra de moda en los últimos tiempos, pero eso no quiere decir que las pruebas de rendimiento no sean un proceso importante en el control de calidad o incluso después de que se haya enviado el producto. Y mientras desarrollo la aplicación, utilizo muchas herramientas diferentes, algunas de ellas mencionadas anteriormente, como el Chrome Profiler , generalmente miro un SaaS o algo de código abierto que puedo poner en marcha y lo olvido hasta que recibo esa alerta que dice que algo se vino abajo. .

Hay muchas herramientas increíbles que lo ayudarán a controlar el rendimiento sin tener que saltar por los aros solo para configurar algunas alertas básicas. Aquí hay algunos que creo que vale la pena echarle un vistazo.

  1. Sematext.com
  2. Datadog.com
  3. Uptime.com
  4. Smartbear.com
  5. Solarwinds.com

Para tratar de pintar una imagen más clara, aquí hay un pequeño tutorial sobre cómo configurar el monitoreo para una aplicación de reacción.

John Demian
fuente
-1

Esta es una buena forma de recopilar información de rendimiento para la operación específica.

start = new Date().getTime(); 
for (var n = 0; n < maxCount; n++) {
/* perform the operation to be measured *//
}
elapsed = new Date().getTime() - start;
assert(true,"Measured time: " + elapsed);
user2601995
fuente