2012-03-30 31 views
11

En el sitio web this hay una lista de variaciones de bucle. Puedo entender el uso del bucle for(var i=0, len=arr.length; i<len ;i++) (donde arr es una matriz), ya que el arr.length no se calcula en cada paso, parece haber una ganancia de rendimiento marginal. Sin embargo, ¿cuáles son las ventajas de usar las otras variantes? Por ejemplo, los bucles comoPara variaciones de bucle en javascript

  1. for (var i=arr.length; i--;)
  2. for (var i=0, each; each = arr[i]; i++)

¿Hay algún cambio notable en el rendimiento mediante el uso de diferentes variaciones de bucle? Generalmente uso for(var i=0, len=arr.length; i<len ;i++) incluso para arreglos muy grandes. Así que solo quiero saber si hay algo que me estoy perdiendo aquí.

+0

"decrementando" el ciclo son mucho más rápidos en js. en cuanto a la última, no la usaría, ya que en js falso == 0 == "". – mpm

+0

posible duplicado de [JavaScript - ¿Los bucles son realmente más rápidos en reversa ...?] (Http://stackoverflow.com/questions/1340589/javascript-are-loops-really-faster-in-reverse) – Matt

+1

@camus El segundo uno puede ser útil cuando se realiza un bucle, p. ej. una colección de elementos DOM. –

Respuesta

6

Es ampliamente considerado que invierte bucle while

var loop = arr.length; 
while(loop--) { 
} 

es el más rápido de tipo bucle disponible en idiomas como C (esto también se aplica a ECMAscript durante bastante tiempo, pero creo que todo depende de a los motores de fecha son bastante parejos en los bucles estándar de hoy). (jsperf)

Su 'variaciones' son en realidad no hay variaciones, pero sólo diferente uso de la declaración conditional dentro del for-loop (que, en realidad hace que sea un variation..doh!). Al igual que

1) for (var i=arr.length; i--;)

sólo utiliza la parte condicional de la for-loop hacer las dos cosas, la iteración y comprobando si i tiene un valor Truthy. Tan pronto como i se convierta en 0, el ciclo finalizará.

2) for (var i=0, each; each = arr[i]; i++)

Aquí tenemos el elemento de cada iteración, por lo que se puede acceder directamente a que dentro del cuerpo del bucle. Esto se usa comúnmente cuando está cansado de repetir siempre arr[ n ].

Le va bien en el almacenamiento en caché de la propiedad .length antes de realizar un bucle. Como mencionaste correctamente, es más rápido porque no tenemos que acceder a esa propiedad en cada iteración. Más allá de eso, también se requiere a veces en scripts DOM, cuando se trata de 'estructuras vivas' como HTMLCollections.

2

El punto es que cuando se disminuye el iterador, en realidad se compara con 0 en lugar de la longitud, que es más rápido ya que los operadores "<, < =,>,> =" requieren controles de tipo en ambos lados izquierdo y derecho del operador para determinar qué comportamiento de comparación se debe usar.

el bucle más rápida es: (Si no se preocupan por el orden, por supuesto)

var i = arr.length 
while(i--) 
{ 
} 

Si no importa el orden, el método que está utilizando está muy bien.

1

Esto es un mal uso de a para cada bucle porque fallará en los valores falsy, rompiendo el bucle.

for (var i=0, each; each = arr[i]; i++) 

Yo tampoco usaría este circuito (incluso si es más rápido ...)

for (var i=arr.length; i--;) 

Parece confuso y es menos legible, también puede escribir como revertir mientras se repite el ciclo.

2

Según jsperf el tipo más rápido de bucle en JavaScript es

var arr = new Array(10); 
var i = 0; 
while (i < arr.length) { 
arr[i]; 
i++; 
}; 

justo por delante de (mi bucle por defecto)

var arr = new Array(10); 
for (var i = 0; i < arr.length; ++i) { 
arr[i]; 
}; 

Con este ser el más lento:

var arr = new Array(10); 
arr.forEach(function(x) { 
x; 
}); 

al menos en Chrome 17 en OSX 10.7.3. ¡Entonces parece que el ciclo "predeterminado" está bien después de todo!

+0

Estas pruebas jsperf son muy útiles. ¡Gracias! –

Cuestiones relacionadas