Aprendí de los libros que deberías escribir para un bucle como este:
for(var i=0, len=arr.length; i < len; i++){
// blah blah
}
entonces el arr.length
que no se calculará cada vez.
Otros dicen que el compilador hará alguna optimización para esto, por lo que puede escribir:
for(var i=0; i < arr.length; i++){
// blah blah
}
Solo quiero saber cuál es la mejor manera en la práctica.
javascript
performance
loops
wong2
fuente
fuente
for ... of
ciclo a esta competencia? La sintaxis parece aún más fácil que un bucle for sin almacenamiento en caché, y quiero saber si debo cambiar a usar for for loops.Respuestas:
Después de realizar esta prueba con la mayoría de los navegadores modernos ...
http://jsben.ch/dyM52
Actualmente , la forma más rápida de bucle (y en mi opinión, la más sintácticamente obvia).
un estándar para bucle con almacenamiento en caché de longitud
Diría que este es definitivamente un caso donde aplaudo a los desarrolladores de motores de JavaScript. Un tiempo de ejecución debe optimizarse para mayor claridad , no inteligencia .
fuente
++i
.for(var i=0, len=myArray.length; i<len; ++i)
Verifique jsperf.com/caching-array-length/84var
declaración. La forma en que se escribe, enlen
realidad , tiene un alcance tal como lo sugiere.La forma más rápida de recorrer una matriz de JavaScript es:
Ver http://blogs.oracle.com/greimer/entry/best_way_to_code_a para una comparación completa
fuente
var
(de lo contrario selen
convierte en una variable global). Además, consulte jsperf.com/loops para obtener más puntos de referencia de bucles.A partir de junio de 2016 , realizando algunas pruebas en el último Chrome (71% del mercado de navegadores en mayo de 2016, y en aumento):
Creo que este hilo es demasiado viejo y es engañoso para los programadores pensar que necesitan almacenar en caché la longitud, o usar recorridos inversos con decrementos para lograr un mejor rendimiento, escribir código que sea menos legible y más propenso a errores que un simple bucle directo. Por lo tanto, recomiendo:
Si su aplicación itera sobre muchos elementos o su código de bucle está dentro de una función que se usa con frecuencia, un bucle directo es la respuesta:
Si su aplicación realmente no recorre muchos elementos o solo necesita hacer pequeñas iteraciones aquí y allá, usar el estándar para cada devolución de llamada o cualquier función similar de su biblioteca JS de elección podría ser más comprensible y menos propenso a errores, ya que El alcance de la variable de índice está cerrado y no necesita usar corchetes, accediendo directamente al valor de la matriz:
Si realmente necesita rascarse unos pocos milisegundos mientras itera sobre miles de millones de filas y la longitud de su matriz no cambia a través del proceso, puede considerar almacenar en caché la longitud en su bucle for. Aunque creo que esto realmente no es necesario hoy en día:
fuente
for(let i=0, j=array.length; i < j; i++)
, los bucles for forward se aceleran considerablemente. En algunas pruebas que ejecuté ganó, en la mayoría estaba dentro del margen de error o el bucle inverso.Si el orden no es importante, prefiero este estilo:
Almacena en caché la longitud y es mucho más corto para escribir. Pero iterará sobre la matriz en orden inverso.
fuente
i--
devuelve un número y una vez que el número es0
la condición esfalse
porqueBoolean(0) === false
.Es solo 2018, por lo que una actualización podría ser agradable ...
Y realmente tengo que estar en desacuerdo con la respuesta aceptada . Se difiere en diferentes navegadores. algunos lo hacen
forEach
más rápido, algunosfor-loop
, y algunoswhile
aquí es un punto de referencia en todos los métodos http://jsben.ch/mW36ey dado que puede ver una gran cantidad de bucles for,
for(a = 0; ... )
entonces vale la pena mencionar que sin las variables 'var' se definirán globalmente y esto puede afectar drásticamente la velocidad, por lo que se ralentizará.El dispositivo de Duff funciona más rápido en la ópera pero no en Firefox
fuente
2014
While
está de vueltaSolo piensa lógico.
Mira este
for
bucle tiene 3 parámetrosAhora dime por qué esto debería ser más rápido que:
while
tiene solo un parámetroEstaba totalmente confundido cuando Chrome 28 mostró que el ciclo for es más rápido que el tiempo. Esto debe haber ben algún tipo de
"Uh, todos están usando el ciclo for, centrémonos en eso cuando desarrollemos para Chrome"
Pero ahora, en 2014, el ciclo while está de vuelta en Chrome. es 2 veces más rápido, en otros navegadores / más antiguos siempre fue más rápido.
Últimamente hice algunas pruebas nuevas. Ahora, en el mundo real, esos códigos cortos no valen nada y jsperf no puede ejecutar correctamente el ciclo while, porque necesita recrear el array.length, lo que también lleva tiempo.
NO PUEDES obtener la velocidad real de un ciclo while en jsperf.
necesita crear su propia función personalizada y verificar eso con
window.performance.now()
Y sí ... no hay forma de que el ciclo while sea simplemente más rápido.
Por ejemplo, tengo una escena de lienzo donde necesito calcular las coordenadas y las colisiones ... esto se hace entre 10-200 MicroSeconds (no milisegundos). En realidad, se necesitan varios milisegundos para procesar todo.
PERO
Hay otra forma súper eficiente usando el para
loop
en algunos casos ... por ejemplo para copiar / clonar una matrizObserve la configuración de los parámetros:
Dicho esto, esto confirma que máquinas como la ...
escribiendo que estaba pensando en hacerlo un poco más corto y eliminar algunas cosas inútiles y escribí este usando el mismo estilo:
Incluso si es más corto, parece que usar
i
una vez más ralentiza todo. Es 1/5 más lento que elfor
bucle anterior y el anteriorwhile
.Nota: el
;
es muy importante después de la de looo sin{}
Incluso si solo te dijera que jsperf no es la mejor manera de probar scripts ... agregué estos 2 bucles aquí
http://jsperf.com/caching-array-length/40
Y aquí hay otra respuesta sobre el rendimiento en javascript
https://stackoverflow.com/a/21353032/2450730
Esta respuesta es para mostrar formas efectivas de escribir javascript. Entonces, si no puede leer eso, pregunte y recibirá una respuesta o leerá un libro sobre javascript http://www.ecma-international.org/ecma-262/5.1/
fuente
for
fue más rápido que elwhile
, y una vez leí en crome-dev que fue exactamente por la razón que mencionas. Sería solo cuestión de tiempo antes dewhile
volver a ponerse al día. ¡A partir de ese momento, la lógica en la primera parte de su respuesta se mantendrá (una vez más, sí)! Sin embargo, las implementaciones modernas ya no siguen rígidamente cada paso especificado por ecma (se optimizan). Como ahora su motor ya no es el cuello de botella más notable, ¡ahora se puede notar la falta de caché de la CPU en bucles inversos !http://jsperf.com/caching-array-length/60
La última revisión de la prueba, que preparé (reutilizando la anterior), muestra una cosa.
La longitud del almacenamiento en caché no es tan importante, pero no hace daño.
Cada primera ejecución de la prueba vinculada anteriormente (en la pestaña recién abierta) da los mejores resultados para los últimos 4 fragmentos (3º, 5º, 7º y 10º en gráficos) en Chrome, Opera y Firefox en mi Debian Squeeze de 64 bits ( mi hardware de escritorio ) Las ejecuciones posteriores dan resultados bastante diferentes.
Las conclusiones de rendimiento inteligente son simples:
!==
lugar de<
.shift()
matriz de destrucción destructiva también es eficiente.tl; dr
Hoy en día (2011.10) el siguiente patrón parece ser el más rápido.
Tenga en cuenta que el almacenamiento en caché
arr.length
no es crucial aquí, por lo que puede probari !== arr.length
y el rendimiento no disminuirá, pero obtendrá un código más corto.PD: Sé que en el fragmento con
shift()
su resultado podría usarse en lugar de acceder al elemento 0, pero de alguna manera pasé por alto eso después de reutilizar la revisión anterior (que tenía errores en los bucles while), y luego no quería perder los resultados ya obtenidos.fuente
¿"Mejor" como en puro rendimiento? o rendimiento Y legibilidad?
El "mejor" rendimiento puro es este, que utiliza un caché y el operador de prefijo ++ (mis datos: http://jsperf.com/caching-array-length/189 )
Yo diría que el for-loop sin caché es el mejor equilibrio en tiempo de ejecución y tiempo de lectura del programador. Cada programador que comenzó con C / C ++ / Java no desperdiciará un ms teniendo que leer este.
fuente
len
se nombre, uno siempre tendría que hacer una doble toma en ese primer ciclo. La intención del segundo bucle es obvia.** almacena en caché la longitud de la matriz dentro del bucle, se eludirán algunos segundos de tiempo. Depende de los elementos de la matriz, si hay más elementos en la matriz, existe una gran diferencia con respecto a Ms de tiempo *
** **
** **
** **
** **
fuente
Esta parece ser la forma más rápida con diferencia ...
Tenga en cuenta que esto consumirá la matriz, la comerá y no dejará nada ...
fuente
arr.shift();
en lugar dearr.pop()
que se pueda evitar la matriz inversa.Es el año 2017 .
Hice algunas pruebas.
https://jsperf.com/fastest-way-to-iterate-through-an-array/
Parece que el
while
método es el más rápido en Chrome.Parece que la disminución izquierda (
--i
) es mucho más rápido que los otros (++i
,i--
,i++
) en Firefox.Este enfoque es el ayuno en promedio. Pero itera la matriz en orden inverso.
Si el orden a futuro es importante, use este enfoque.
fuente
let
, en realidad está comparando el rendimiento de la creación del alcance en lugar del rendimiento del bucle. El usolet i = 0, ii = array.length
en susfor
bucles creará un nuevo alcance para esas variables dentro delfor
bloque. Suswhile
ejemplos no crean un nuevo alcance para las variables dentro delwhile
bloque y es por eso que son más rápidas. Si usa envar
lugar delet
en sus bucles for, verá que los bucles for siguen siendo tan rápidos como en 2017, pero más legibles.var
ylet
tienen el mismo rendimiento - stackoverflow.com/a/32345435/1785975while
ser más rápido en Chrome" precisa. Es solo si se usalet
debido a problemas de rendimiento de esa palabra clave en Chrome. Si usavar
o con otros navegadores,for
ywhile
son más o menos lo mismo, a vecesfor
es aún más rápido dependiendo del punto de referencia, y es más compacto y legible en mi humilde opinión.Siempre escribo en el primer estilo.
Incluso si un compilador es lo suficientemente inteligente como para optimizarlo para matrices, ¿pero aún así es inteligente si estamos usando DOMNodeList aquí o algún objeto complicado con longitud calculada?
Sé cuál es la pregunta sobre las matrices, pero creo que es una buena práctica escribir todos sus bucles en un estilo.
fuente
i ++ es más rápido que ++ i, --i e i--
Además, puede guardar la última línea haciendo arr [i ++] la última vez que necesita acceder a i (pero esto puede ser difícil de depurar).
Puede probarlo aquí (con otras pruebas de bucle): http://jsperf.com/for-vs-whilepop/5
fuente
++i
es más rápido ...A partir de septiembre de 2017, estas pruebas jsperf muestran que el siguiente patrón es el más eficaz en Chrome 60:
¿Alguien puede reproducirse?
fuente
He intentado otras formas de iterar una gran matriz y descubrí que reducir a la mitad la longitud de la matriz y luego iterar ambas mitades en un solo bucle es más rápido. Esta diferencia de rendimiento se puede ver al procesar grandes matrices .
Alguna comparación de rendimiento (usando timer.js) entre la longitud en caché for-loop VS el método anterior.
http://jsfiddle.net/tejzpr/bbLgzxgo/
fuente
Otra prueba de jsperf.com: http://jsperf.com/while-reverse-vs-for-cached-length
El bucle while inverso parece ser el más rápido. El único problema es que mientras (--i) se detendrá en 0. ¿Cómo puedo acceder a la matriz [0] en mi bucle entonces?
fuente
while (i--)
entonces la veracidad dei
será probada antes de disminuir en lugar de disminuir y luego probar la veracidad.Un ciclo while básico es a menudo el más rápido. jsperf.com es un gran sandbox para probar este tipo de conceptos.
https://jsperf.com/fastest-array-loops-in-javascript/24
fuente
Mientras que el bucle es un poco más rápido que para el bucle.
Use el bucle while en su lugar
fuente
El enfoque más rápido es el tradicional para el bucle. Aquí hay una comparación de rendimiento más completa.
https://gists.cwidanage.com/2019/11/how-to-iterate-over-javascript-arrays.html
fuente
La solución más elegante que conozco es usar el mapa.
fuente
Prueba esto:
fuente
La forma más rápida de recorrer una matriz es usando el filtro. El método filter () crea una nueva matriz con todos los elementos que pasan la prueba implementada por la función proporcionada.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
Desde mi experiencia, siempre prefiero filtros, mapas, etc.
fuente
A partir de 2019, WebWorker ha sido más popular, para grandes conjuntos de datos, podemos usar WebWorker para procesar mucho más rápido mediante el uso completo de procesadores multi-core.
También tenemos Parallel.js que hacen que WebWorker sea mucho más fácil de usar para el procesamiento de datos.
fuente