2011-12-31 9 views
38

Teniendo en cuenta este códigoiteración a través de una matriz más rápido hacia atrás y luego hacia delante

var arr = []; 
    for (var i = 0; i < 10000; ++i) { 
     arr.push(1); 
    } 

Delanteros

for (var i = 0; i < arr.length; ++i) {; 
} 

revés

for (var i = arr.length - 1; i >= 0; --i) {; 
} 

codificado F orward

for (var i = 0; i < 10000; ++i) {; 
} 

qué es backwords mucho más rápido?

Aquí está la prueba http://jsperf.com/array-iteration-direction

+6

Tenga en cuenta que su caso al revés debería comenzar en 'arr.length-1' y tener' i> = 0' en lugar de 'i> 0'. – nnnnnn

+1

El título es engañoso. Ya no es el caso que el uso directo de arr.length * sea * más lento en los navegadores avanzados. – user2864740

+0

posible duplicado de [rendimiento del bucle de JavaScript - ¿Por qué es disminuir el iterador hacia 0 más rápido que el incremento] (http://stackoverflow.com/q/3520688/1048572) – Bergi

Respuesta

63

Debido a que su hacia delante condición tiene que recibir la propiedad length de la matriz cada vez, mientras que la otra condición sólo tiene para verificar "mayor que cero", una tarea muy rápida.

Cuando su longitud de la matriz no cambia durante el ciclo, y que realmente mira ns-Desempeño, puede utilizar

for (var i=0, l=arr.length; i<l; i++) 

Por cierto: En lugar de for (var i = arr.length; i > 0; --i) puede utilizar for (var i = arr.length; i-- > 0;) lo que realmente funciona a través de la matriz de n-1 a 0, no de n a 1.

+0

Sí, así es como lo hago para las funciones optimizadas. Solo tenga en cuenta que si la matriz es mutable (y generalmente no lo es), esto puede omitir uno o dos recursos. Por ejemplo, esto no funcionará si está pasando por los elementos que el bucle mismo está agregando o eliminando. –

+3

incluso puede hacer 'for (...; i--;)' – ajax333221

+0

así que básicamente significa que si no cambio la matriz y mantengo array.length en una variable, entonces ¿velocidad hacia atrás = velocidad de avance? Ejemplo: var longitud = array.length; para (var i = 0; i

8

Debido a que en la primera forma se accede a la propiedad de la matriz lengtharr una vez por cada iteración, mientras que en el segundo sólo lo hace una vez.

+0

@samccone - ¿Qué resultado está viendo (qué prueba en la que navegador)? Estoy viendo que el almacenamiento en caché de la longitud siempre es al menos tan rápido y generalmente más rápido. – jfriend00

+0

bien, tienes razón ... parece que en realidad es una mezcla de resultados, pero el almacenamiento en caché sí lo ayuda ... gracias XD – samccone

2

i > 0 es más rápido que i < arr.length y se está produciendo en cada iteración del ciclo.

Usted puede mitigar la diferencia con esto:

for (var i = 0, len = arr.length; i < len; ++i) {; 
} 

Esto todavía no es tan rápido como el elemento hacia atrás, pero más rápido que su opción de desvío.

+0

mira la prueba codificada http://jsperf.com/array-iteration-direction ... usando tu lógica, debería ser más rápido, ¿no? – samccone

5

Si desea tenerlos al mismo ritmo, puede hacerlo para la iteración directa;

for(var i=0, c=arr.length; i<c; i++){ 
} 

Por lo tanto, su secuencia de comandos no tendrá que tomar la longitud de la matriz en everystep.

+0

Ahhh ... interesante su método ahora toma la corona para la iteración más rápida http://jsperf.com/array-iteration-direction – samccone

1

Y estos son igualmente buenos:

var arr= [], L= 10000; 
while(L>-1) arr[L]= L--; 

O

var arr= [], i= 0; 
while(i<10001) arr[i]=i++; 
+0

hahaha complicado complicado – samccone

+0

Debe ser 'while (- L> = 0) arr [L] = L; ' –

4

no estoy completamente seguro de esto, pero aquí es mi suposición:

Para el siguiente código:

for (var i = 0; i < arr.length; ++i) {; 
} 

D Durante el tiempo de ejecución, hay un cálculo arr.length después de cada pase de bucle. Esta puede ser una operación trivial cuando está sola, pero puede tener un impacto cuando se trata de arreglos múltiples/enormes. Se puede tratar lo siguiente:

var numItems = arr.length; 
    for(var i=0; i< numItems; ++i) 
    { 
    } 

En el código anterior, se calcula la longitud de la matriz sólo una vez, y operar con ese número calculado, en lugar de realizar el cálculo de la longitud una y otra vez.

De nuevo, solo estoy expresando mis pensamientos aquí. Observación interesante de hecho!

1

hazlo como a continuación, funcionará de la misma manera.porque arr.length lleva tiempo en cada iteración en avance.

int len = arr.length; 

hacia adelante

for (var i = 0; i < len; ++i) { 
} 

hacia atrás

for (var i = len; i > 0; --i) { 
} 
+0

El caso al revés no es correcto. Lo que hago es 'for (i = len; --i> = 0;) {' –

Cuestiones relacionadas