Uno de los tips más recomendados para optimizar tu código JavaScripts recomienda chachear las longitudes de los arreglos (Arrays) a la hora de iterarlos.
Normalmente la manera más común de iterar sobre un arreglo es la siguiente:
1 2 3 4 | var arr = [ 'a', 'b', 'c' ] ;for (var i = 0; i < arr.length; i++) { console.log(arr[i]);}; |
Ejemplo 1
El referido tips consiste en almacenar la longitud del arreglo en una variable antes de recorrerlo, con el objetivo de no tener que recalcular dicha longitud en cada iteración. Esto se haría de la siguiente manera:
1 2 3 4 | var arr = ['a', 'b', 'c'] ;for (var i = 0, long = arr.length; i < long; i++) { console.log(arr[i]);}; |
Ejemplo 2
Pero bien. ¿Realmente este tips es necesario? ¿Se recalcula la longitud del arreglo en cada iteración?
Ya han de suponer que las respuestas para estas dos preguntas son no. Claramente, y explico por qué.
La longitud en los arreglos de JavaScripts nos es más que una propiedad (length) que se actualiza al insertar o extraer elementos del arreglo. Esto permite que se pueda acceder a ella directamente de igual manera que como se hace con las propiedades de los objetos, puesto que en JavaScripts los arreglos son objetos. La complejidad de acceder a cualquier propiedad de un objeto es la misma que la de acceder a una variable (Complejidad temporal lineal O(1)). Por lo tanto, la forma tradicional de iterar los arreglos (ejemplo 1) no tiene ningún inconveniente según lo planteado, dejando la recomendación del ejemplo 2 sin validez.
Para finalizar acá les dejo con una de las funciones de los arreglos, muy útil para recorrerlos “de punta a cabo”. En el próximo post escribiré algunas cosas más sobre los arreglos en JavaScripts y su propiedad length.
1 2 3 4 | ['a', 'b', 'c'].forEach( function (elem, index) { console.log('En la posición: ' + index + ' se encuentra el elemento: ' + elem);}); |





@Julio Cesar, La recomendación del ejemplo 2 tiene mucha validez. Los objetos guardan sus propiedades mediante una tabla hash. El acceso a una tabla hash es O(1) pero requiere un calculo (Ojo con esto, para encontrar el indice en la tabla) de todas maneras y ese calculo para leer el valor de «length» es ejecutado N veces, mientras que cacheando «length» el calculo se realiza una vez.
En fin, ambas complejidades son O(1) pero el ejemplo 2 tiene mayor rendimiento.
Saludos.
Gracias por tu comentario. Dejar claro que leer un valor de una variable o de una propiedad de un objeto es de complejidad temporal O(1), ambas se gestionan de igual modo por el lenguaje. Cuando se cachea el valor del «length» como en el ejemplo 2, durante la iteración del arreglo este valor no es actualizado si se modifica la longitud, pues como decís este es leído una sola vez, lo que puede ser ventajoso en determinados casos.
Haz una prueba de rendimiento y veras la diferencia, en caso que dentro del ciclo se modifiquen los items del arreglo la primera opción es la indicada pero en caso contrario (que es la gran mayoría de los casos) el segundo ofrece mejor rendimiento.
for (var i in data.list_users) {
console.log(‘En la posición: ‘ + i + ‘ se encuentra el elemento: ‘ + data.list_users[i]);
}
Pues bueno, acá le comparto mis experiencias con unos ejemplos, asumiendo que todos usamos Firebug, solo peguen el código que les comparto a cotinuación en la consola de dicha herramienta.
//Inicialmente creamos un Super-Array :)
var array = [];
for (var i=0;i<=500000;i++){
array[i]=i;
}
//Medimos el Tiempo de la Propuesta 1
var inicio = +new Date();
for (var i=0;i<= array.length;i++){
array[i];
}
console.log("Duración: " + (+new Date() - inicio) + "ms");
//Medimos el Tiempo de la Propuesta 2
inicio = +new Date();
var length = array.length;
for (var i=0;i<= length;i++){
array[i];
}
console.log("Duración: " + (+new Date() - inicio) + "ms");
//Y esta la que mejores resultados me ha dado
inicio = +new Date();
var length = array.length;
for (var i=0;i<= length;i+=1){
array[i];
}
console.log("Duración: " + (+new Date() - inicio) + "ms");
//Esta es la menos eficiente de todas
inicio = +new Date();
for (var i in array) {
array[i];
}
console.log("Duración: "+ (+new Date() - inicio) + "ms");
Saludos!
Al final el mejor consejo para iterar es utilizar:
i+=1en vez dei++Segun mi experiencia esta es la manera mas rapidas de iterar arrays y es la que uso, no he encontrado otra mas rapida:
var length = array.length, i = 0;
while (++i <= length){
array[i];
}
Estimado, sin dudas recorrer un array de la manera que dices es la más rápida, mi experiencia coincide. Pero el ejemplo que pones tiene unos pequeños problemitas: No tiene en cuenta la posición inicial del arreglo (array[0]), pues ++i incrementa i y luego opera con su valor.Además evalúa el array una posición fuera del rango por poner «<= length". De esta manera resulta mejor:
var long = array.length, i = 0;
while (i < long){
array[i++];
}
Oops! mala mia, el snipet fue escrito burdamente para usarlo con la prueba de rendimiento propuesta anteriormente por @Josh.
Pero en un caso practico seria:
var length = array.length, i = -1;
while (++i < length){
array[i];
}
bueno, mis tiempos fueron esto:
Duración: 724ms
Duración: 695ms
Duración: 689ms
Duración: 555ms
en teoría la última que dices que es la menos eficiente es la que menos tiempo consume
Bueno, algo de razón llevas:
En Chrome 37 los resultados coinciden con lo que planteas.
Duración: 490ms
Duración: 455ms
Duración: 453ms
Duración: 373ms
Firefox 31:
Duración: 224ms
Duración: 216ms
Duración: 200ms
Duración: 344ms
Internet Explorer 10:
Duración: 85ms
Duración: 76ms
Duración: 75ms
Duración: 152ms
HOlaaaa. Quiero aprender a desarrollar addons para firefox pero no se por donde empezar y no veo en el sitio bibliografia y herramientas. Alguien me puede ayudar??
Puedes descargar el Addon-SDK (https://firefoxmania.uci.cu/common/SDKs/addon-sdk-1.17.zip)
Dentro esta toda la documentacion que necesitas
Otra forma que les aconsejo es:
var arr = [ ‘a’, ‘b’, ‘c’ ];
for(arr in a){
console.log(a);
}
Como pueden ver es mas intuitivo y elegante.
Salu2s.
En ES6 han introducido iteradores y for-of, en el caso de for-of aconsejan su uso sobre forEach pues se pueden interrumpir el ciclo, retornar valores y continuar.
for (var value of myArray) {
console.log(value);
}
Si desean saber mas pueden visitar Mozilla Hacks https://hacks.mozilla.org/2015/04/es6-in-depth-iterators-and-the-for-of-loop/
Alguien me puede proporcionar algo de documentación para iniciarme en la programación de plugins para firefox, la verdad estuve buscando un poco y no encontré algo que me inicie, es decir que me explique como es la estructura, donde va cada cosa y demas.. Saludos y Gracias de antemano.
PD: Mi email no se si lo pueda poner aquí, de todos modos lo hago para que me puedan contactar:
Creo que quisisteis decir complementos o addon en inglés, realmente tengo pensado comenzar una serie de artículos referentes al tema, la primera entrega a sido sobre la herramienta para gestionar la creación y tal…
https://developer.firefoxmania.uci.cu/2015/07/02/que-es-jpm-y-porque-deberiamos-usarlo/
En la medida de mi disponibilidad de tiempo, pondré algunos más sobre ejemplos simples de como crearlos y trabajar con las APIs, pero toda la información que consultamos está en la red de desarrolladores de mozilla
https://developer.mozilla.org/en-US/Add-ons
De momento está en inglés, cualquier duda coméntanos haber si podemos ayudarte!