2012-03-09 8 views
16

La mayoría de los casos de uso del método reduce() pueden reescribirse fácilmente con un ciclo for. Y las pruebas en JSPerf muestran que reduce() suele ser un 60% -75% más lento, dependiendo de las operaciones realizadas dentro de cada iteración.¿Hay algún beneficio real para usar el método javascript Array reduce()?

¿Hay alguna razón real para utilizar reducir() entonces, aparte de ser capaz de escribir código en un 'estilo funcional'? Si puede obtener una ganancia de rendimiento del 60% al escribir solo un poco más de código, ¿por qué alguna vez usaría reducir()?

EDIT: De hecho, otros métodos funcionales como forEach() y mapa() todas muestran un rendimiento similar, siendo al menos un 60% más lento que simple para bucles.

Aquí hay un enlace a la prueba JSPerf (con llamadas de función): forloop vs forEach

Respuesta

5
  • Es posible que desee alcance. Por ejemplo, es posible que desee realizar funciones de devolución de llamada o referencias a objetos javascript. Para obtener más información, vea por qué JavaScript no tiene un ámbito bloqueado. [editar: moderno javascript ahora admite let variables. Volver antes de ESv6, cuando declarado una variable var, ¡Gracias izada como si hubiera sido escrito en la parte superior del bloque de código de función, tan a menudo había que escribir para cuerpos de bucles como funciones. Sin embargo, esto sigue siendo válido:] Si tiene una función escrita, también podría usar un estilo funcional a menos que sea un cuello de botella significativo.
  • Su código no siempre necesita para funcionar a plena velocidad de la máquina. Es posible que ni siquiera esté optimizando el código en el cuello de botella.
  • Además usted no proporciona su "prueba de JSPerf" por lo que podemos criticarla. Por ejemplo, si ya tiene una función de reducción (o mapa o para cada función), entonces apuesto a que la actuación sería a la par. Incluso si no es así, la metodología de prueba puede ser defectuosa, especialmente teniendo en cuenta que muchos navegadores pueden optimizar de forma diferente o tener una sobrecarga de llamada de función diferente.

sidenote: se trata de una comparación de rendimiento válida entre la sintaxis, pero una comparación rendimiento inválida en cuando sintaxis no es la cuestión que nos ocupa:

myArray.map(function(x){return x+1}) 

// ...versus... 

for(var i=0; i<myArray.length; i++) { 
    myArray[i] = myArray[i]+1; 
} 

Esta sería una comparación de rendimiento válido:

myArray.forEach(function(x){return x+1}) 

// ...versus... 

var plusOne = function(x){return x+1}; 
for(var i=0; i<myArray.length; i++) { 
    plusOne(myArray[i]); 
} 

// (may need a side-effect if the compiler is smart enough to optimize this) 

(también en respuesta a su edición: .forEach() y .map() proporcionan mucha más claridad, y evitar la necesidad para el lazo explícito int i=0; i<array.length; i++ argumentos.)

+2

estoy de acuerdo con usted acerca de lo que constituye una comparación de rendimiento válido. El _primero_ es la comparación válida, porque seguramente (para su ejemplo) la pregunta es "¿Qué método es más rápido agregando uno a cada elemento de la matriz?", No "¿Qué método es el más rápido pero cualquier método que no utiliza una llamada de función es descalificado? de la entrada ". Estoy de acuerdo en que si asumes que quieres una función de todos modos para fines de alcance/cierre, entonces también podrías usar '.reduce()' o '.forEach()' o lo que sea. – nnnnnn

+0

La pregunta es exactamente sobre la sintaxis, por lo que es una comparación de rendimiento válida. Tal vez debería reformular la pregunta en un escenario en el que quieras exprimir cada bit de rendimiento posible. En ese caso, no puedo encontrar una buena razón para no usar un ciclo for simple. ¿Puede proporcionar un ejemplo concreto en el que el alcance es absolutamente necesario? –

+0

@EvanYou: '[1,2,3].forEach (function (x) {setTimeout (function() {alert (x)}, 1000)}) '(alerts 1,2,3) contra' for (var i = 0; i <4; i ++) {setTimeout (función() {alerta (i)}, 1000)} '(alertas 4,4,4) – ninjagecko

Cuestiones relacionadas