2011-09-07 15 views
9

Hace dos días, cuando encontré jsperf.com que tiene una colección de muchas pruebas de rendimiento de JavaScript, examiné varias pruebas.¿Por qué Firefox y otros navegadores funcionan de manera opuesta al calcular qué número es más grande?

Una de las pruebas fue this, que compara Math.min(a,b) vs a<b?a:b. Cuando ejecuté esta prueba en Google Chrome, resultó que a<b?a:b es mucho más rápido que Math.min(a,b) (en Chrome 14, el primero es 53,661,381 ops/s y el segundo es 419,830,711 ops/s). Otros navegadores web tienen resultados similares.

Sin embargo, en Firefox, el resultado es opuesto. Math.min(a,b) es mucho más rápido que a<b?a:b! El primero es 374,219,869 ops/s y segundo es 79,490,749 ops/s en Firefox 6.

enter image description here

Cuando publiqué esto en Facebook, alguien dijo que "Dado que Firefox es un proyecto de código abierto, los desarrolladores han optimizado Math.min, pero Google Chrome no lo hizo , ya que Google Chrome es solo una modificación de Chromium ", pero (al margen de esa declaración anterior no es del todo correcta) no tiene sentido, porque eso no explica la razón por la cual a<b?a:b de Google Chrome y Math.min(a,b) de Firefox funcionan con velocidad similar, y Google El Math.min(a,b) de Chrome y el a<b?a:b de Firefox funcionan a la misma velocidad, porque si Firefox es más rápido que Google Chrome, entonces Googl El Math.min(a,b) de Chrome debería ser mucho más lento que el a<b?a:b de Firefox.

Resumen:

  1. En los otros navegadores, a<b?a:b es más rápido que Math.min(a,b).
  2. Sin embargo, en Firefox, Math.min(a,b) es más rápido que a<b?a:b.
  3. Puesto que la velocidad de Math.min(a,b) en Firefox ≒ la velocidad de a<b?a:b en Google Chrome y la velocidad de a<b?a:b en Firefox ≒ la velocidad de Math.min(a,b) en Google Chrome, "Firefox es lento" o "Firefox es rápido" no puede ser una razón .

¿Hay alguna razón por la que (cómo) sucede esto?

+4

¿Razón? Además de eso, cada uno de los navegadores nombrados tiene sus propias implementaciones de JavaScript y, por lo tanto, pueden optimizar de la forma que deseen. – Jamiec

+0

@Jamiec Pero creo que 'a JiminP

+0

@Jiminip La llamada a' Math.min' se compilará y el método tal vez estará en línea. Tal vez en Firefox está en línea con código súper rápido, mientras que el 'si' sigue siendo un' si'. – xanatos

Respuesta

8

Aquí están sucediendo algunas cosas.

Antes que nada, en Firefox 6 hay dos compiladores JIT diferentes: TraceMonkey y JaegerMonkey. Cuál se usa para un determinado bit de código depende de algunas heurísticas; estas heurísticas tienden a favorecer a TraceMonkey para el código con llamadas a funciones. Sucede que para un código lo suficientemente simple, TraceMonkey casi siempre es más rápido que JaegerMonkey; ese es el caso para ambos fragmentos de código presentados aquí, en particular.

En este punto de referencia particular, el Math.min codepath se compila con Tracemonkey, porque es una llamada a función. El código de ruta del operador trinario se compila con JaegerMonkey.

Puede experimentar con esto yendo a about:config, poniendo jit en el campo de filtro y deshabilitando uno o ambos de TraceMonkey (tracejit en la lista) y JaegerMonkey (methodjit).Si lo hace, verá que en este punto de referencia particular el operador trinario es más rápido que Math.min para cada uno de los compiladores individualmente, por lo que la inversión que está viendo en comparación con otros navegadores es solo una función del uso de compiladores diferentes.

Ahora en cuanto a por qué Math.min es típicamente más lento que el operador trinario ... antes que nada tiene que hacer más trabajo; las respuestas que devuelve NO son las mismas que las del operador trinario, si lo prueba cuidadosamente. En segundo lugar, generalmente se implementa como una llamada a función, que es de donde proviene la mayoría de los gastos generales (aunque TraceMonkey en realidad lo hace explícitamente en el código generado, por lo que el rendimiento de los dos fragmentos no es muy diferente en TraceMonkey).

1

Tuve esta misma pregunta después de leer, Efficient Javascript en Dev.Opera, y ejecutar algunos puntos de referencia diferentes. Creo que esa sección es un poco engañosa. Hay muchas cosas que ralentizan Math.min, pero nada de eso realmente explica el rendimiento en Google Chrome contra Firefox o IE9.

cosas que pienso ralentizar Math.min

  • hace uso de los argumentos objeto
  • hay que verificar si cualquier valor es NaN
  • otras cosas como volver infinito si no se dan argumentos y + 0> -0

Para obtener información más detallada, consulte http://qfox.nl/ecma/366 para ver una implementación de muestra.

P.S. Sé que esta pregunta es antigua, pero creo que podría ahorrarme un poco de tiempo si alguna vez viajo al pasado.

Cuestiones relacionadas