2010-04-30 17 views
12

EsJavascript para la eficiencia de bucle

for (var i=0, cols=columns.length; i<cols; i++) { ... } 

más eficiente que

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

?

En la segunda variante, ¿se calcula columns.length cada vez que se comprueba la condición i<columns.length?

+2

ADVERTENCIA: Asegúrese de que los cols se declara con var ** ** ** y en el interior de una función **. A menos que ambos sean así, JavaScript podría tratarlo como una variable global (y, por lo tanto, hacer que los accesos sean más lentos). Los navegadores basados ​​en WebKit prácticamente ignoran var en el ámbito global, incluso si la variable en cuestión entra en conflicto con una variable global (como 'status', por ejemplo). –

+2

@Joey Adams: 'var i = 0, cols = columns.length' declarará cols como var, ¿verdad? – StriplingWarrior

Respuesta

8

Cualquier expresión que está en la segunda porción de un para serán evaluados una vez por bucle.

Por lo tanto, aquí, con su segunda proposición, sí, columns.length se calculará cada vez que se compruebe la condición, lo que haría la primera proposición más rápida que la segunda.


(Eso es cierto para muchos otros idiomas, por cierto)

+1

Esto no soluciona si un tiempo de ejecución inteligente de JS podría optimizarlo. –

+3

probado en Chrome y Firefox (ambos de los cuales utilizan actualmente la compilación dinámica), y en ambos, el almacenamiento en caché 'columns.length' con una variable local es más rápido que usar' columnas.longitud' en el ciclo. –

+1

@Joey Adams: Solo por curiosidad, ¿cuánto más rápido es? ¿Es este el tipo de cosa que clasificarías como una optimización prematura en la mayoría de los casos? – StriplingWarrior

5

optimizaciones Micro como esta no hacen sentido enorme en un lenguaje como Javascript a menos que haya probado y el rendimiento de los bucles a ser un problema .

Sin embargo, columns.length debe ser evaluado en cada iteración porque el número de columnas puede cambiar durante una iteración del bucle. Por lo tanto, almacenar el límite de bucle puede proporcionar un rendimiento ligeramente mejor (pero vea mi primer punto).

0

Sí, lo es. El acceso a la propiedad de longitud no requiere tiempo innecesario (a menos que la longitud de la matriz pueda cambiar durante la iteración).

Aquí es cómo bucle a través de matrices: http://gist.github.com/339735

1

Tenga en cuenta que la mayoría de estos bucles requieren una declaración adicional en el bucle para recuperar realmente el elemento i-ésimo de la matriz. Usted puede evitar esto y conseguir un bucle muy rápido con la siguiente variante, que se aprovecha del hecho de que Javascript sólo devuelve indefinido (que se evalúa como falsa), si tiene acceso a una matriz con una salida de índice de límites (en lugar de elevar un error):

for (var i = 0, col, col = columnas [i]; i ++) {...}

Obviamente esto no funciona si está iterando a través de una matriz que contiene elementos que evaluarían a falso.

Cuestiones relacionadas