He escuchado esto varias veces. ¿Los bucles de JavaScript son realmente más rápidos al contar hacia atrás? Si es así, ¿por qué? ¡He visto algunos ejemplos de conjuntos de pruebas que muestran que los bucles invertidos son más rápidos, pero no puedo encontrar ninguna explicación de por qué!
Supongo que es porque el ciclo ya no tiene que evaluar una propiedad cada vez que verifica si está terminado y solo verifica el valor numérico final.
Es decir
for (var i = count - 1; i >= 0; i--)
{
// count is only evaluated once and then the comparison is always on 0.
}
for
bucle hacia atrás es más rápido porque la variable de control del bucle de límite superior (jeje, límite inferior) no tiene que definirse o extraerse de un objeto; Es un cero constante.Respuestas:
No es que
i--
sea más rápido quei++
. En realidad, ambos son igualmente rápidos.Lo que lleva tiempo en los bucles ascendentes es evaluar, para cada uno
i
, el tamaño de su matriz. En este bucle:Evalúa
.length
solo una vez, cuando declarai
, mientras que para este cicloevalúa
.length
cada vez que incrementai
, cuando verifica sii <= array.length
.En la mayoría de los casos , ni siquiera debería preocuparse por este tipo de optimización .
fuente
.length
un cierto número de veces o declarar y definir una nueva variable? En la mayoría de los casos, esta es una optimización prematura (e incorrecta), a menos quelength
sea muy costoso evaluarlo.0
es más rápido de evaluar quearray.length
. Bueno, supuestamente.length
se declarafor loop
o no.Este tipo comparó muchos bucles en javascript, en muchos navegadores. También tiene un conjunto de pruebas para que pueda ejecutarlos usted mismo.
En todos los casos (a menos que me perdí uno en mi lectura) el ciclo más rápido fue:
fuente
--i
entonces tienes que usarvar current = arr[i-1];
dentro del bucle o será desactivado por uno ...Intento dar una imagen amplia con esta respuesta.
Lo siguiente entre paréntesis fue mi creencia hasta que recientemente probé el problema:
[[En términos de lenguajes de bajo nivel como C / C ++ , el código se compila para que el procesador tenga un comando de salto condicional especial cuando una variable es cero (o no cero).
Además, si te importa esta optimización, puedes ir en
++i
lugar de hacerloi++
, porque++i
es un comando de procesador único, mientras quei++
significaj=i+1, i=j
.]]Se pueden hacer bucles realmente rápidos desenrollando:
Puede ser mucho más lento que
pero las razones para esto pueden ser bastante complicadas (solo por mencionar, hay problemas de preprocesamiento de comandos de procesador y manejo de caché en el juego).
En términos de lenguajes de alto nivel , como JavaScript, tal como lo solicitó, puede optimizar las cosas si confía en bibliotecas, funciones integradas para bucles. Déjelos decidir cómo se hace mejor.
En consecuencia, en JavaScript, sugeriría usar algo como
También es menos propenso a errores y los navegadores tienen la oportunidad de optimizar su código.
[OBSERVACIÓN: no solo los navegadores, sino que también tiene un espacio para optimizar fácilmente, simplemente redefina la
forEach
función (dependiendo del navegador) para que utilice el mejor truco más reciente. :) @AMK dice que en casos especiales vale la pena usararray.pop
oarray.shift
. Si haces eso, ponlo detrás de la cortina. La mayor exageración es agregar opcionesforEach
para seleccionar el algoritmo de bucle.]Además, también para los idiomas de bajo nivel, la mejor práctica es utilizar alguna función de biblioteca inteligente para operaciones complejas en bucle si es posible.
Esas bibliotecas también pueden poner cosas (multiproceso) a sus espaldas y también los programadores especializados las mantienen actualizadas.
Hice un poco más de escrutinio y resultó que en C / C ++, incluso para las operaciones 5e9 = (50,000x100,000), no hay diferencia entre subir y bajar si la prueba se realiza contra una constante como dice @alestanis. (Los resultados de JsPerf a veces son inconsistentes, pero en general dicen lo mismo: no se puede hacer una gran diferencia).
Por lo tanto,
--i
resulta ser algo "elegante". Solo te hace ver como un mejor programador. :)Por otro lado, para desenrollarme en esta situación de 5e9, me ha bajado de 12 segundos a 2.5 segundos cuando pasé 10 segundos, y a 2.1 segundos cuando pasé 20 años. Fue sin optimización, y la optimización ha reducido las cosas a poco tiempo inconmensurable. :) (El desenrollado se puede hacer en mi forma anterior o usando
i++
, pero eso no adelanta las cosas en JavaScript).En general: mantenga
i--
/i++
y++i
/i++
diferencias en las entrevistas de trabajo, cumplaarray.forEach
u otras funciones complejas de la biblioteca cuando estén disponibles. ;)fuente
array.each(...)
. No creo que intenten experimentar con la liberación de bucles for simples.+1
para conseguirte unaGreat Answer
insignia. Muy buena respuesta. :)i--
es tan rápido comoi++
Este código a continuación es tan rápido como el suyo, pero usa una variable adicional:
La recomendación es NO evaluar el tamaño de la matriz cada vez. Para grandes matrices se puede ver la degradación del rendimiento.
fuente
for (var i=0, up=Things.length; i<up; i++) {}
Dado que está interesado en el tema, eche un vistazo a la publicación del blog de Greg Reimer sobre un punto de referencia de bucle de JavaScript, ¿Cuál es la forma más rápida de codificar un bucle en JavaScript? :
También puede hacer una prueba de rendimiento en un bucle abriendo
https://blogs.oracle.com/greimer/resource/loop-test.html
(no funciona si JavaScript está bloqueado en el navegador por, por ejemplo, NoScript ).EDITAR:
Un punto de referencia más reciente creado por Milan Adamovsky se puede realizar en tiempo de ejecución aquí para diferentes navegadores.
Para una prueba en Firefox 17.0 en Mac OS X 10.6 , obtuve el siguiente bucle:
como el más rápido precedido por:
fuente
No es el
--
o++
, es la operación de comparación. Con--
puedes usar una comparación con 0, mientras que con++
necesitas compararlo con la longitud. En el procesador, comparar con cero está normalmente disponible, mientras que comparar con un entero finito requiere una resta.a++ < length
en realidad se compila como
Por lo tanto, lleva más tiempo en el procesador cuando se compila.
fuente
Respuesta corta
Para el código normal, especialmente en un lenguaje de alto nivel como JavaScript , no hay diferencia de rendimiento en
i++
yi--
.El criterio de rendimiento es el uso en el
for
ciclo y la declaración de comparación .Esto se aplica a todos los lenguajes de alto nivel y es principalmente independiente del uso de JavaScript. La explicación es el código de ensamblador resultante en la línea inferior.
Explicación detallada
Una diferencia de rendimiento puede ocurrir en un bucle. El trasfondo es que en el nivel del código del ensamblador puede ver que a
compare with 0
es solo una declaración que no necesita un registro adicional.Esta comparación se emite en cada paso del ciclo y puede resultar en una mejora del rendimiento medible.
será evaluado a un pseudo código como este:
Tenga en cuenta que 0 es un literal, o en otras palabras, un valor constante.
será evaluado a un pseudocódigo como este (se supone que la optimización del intérprete normal):
Tenga en cuenta que end es una variable que necesita un registro de CPU . Esto puede invocar un intercambio de registro adicional en el código y necesita una declaración de comparación más costosa en la
if
declaración.Solo mis 5 centavos
Para un lenguaje de alto nivel, la legibilidad, que facilita el mantenimiento, es más importante como una mejora de rendimiento menor.
Normalmente, la iteración clásica de principio a fin de matriz es mejor.
La iteración más rápida desde el final de la matriz al inicio da como resultado la secuencia inversa posiblemente no deseada.
Post scriptum
Como se preguntó en un comentario: La diferencia de
--i
yi--
está en la evaluación dei
antes o después de la disminución.La mejor explicación es probarlo ;-) Aquí hay un ejemplo de Bash .
fuente
--i
yi--
también?He visto la misma recomendación en Sublime Text 2.
Como ya se dijo, la mejora principal no es evaluar la longitud de la matriz en cada iteración en el bucle for. Esta es una técnica de optimización bien conocida y particularmente eficiente en JavaScript cuando la matriz es parte del documento HTML (haciendo un
for
para todos losli
elementos).Por ejemplo,
for (var i = 0; i < document.getElementsByTagName('li').length; i++)
es mucho más lento que
for (var i = 0, len = document.getElementsByTagName('li').length; i < len; i++)
Desde mi punto de vista, la principal mejora en el formulario en su pregunta es el hecho de que no declara una variable adicional (
len
en mi ejemplo)Pero si me preguntas, no se trata de la optimización
i++
vsi--
, sino de no tener que evaluar la longitud de la matriz en cada iteración (puedes ver una prueba de referencia en jsperf ).fuente
No creo que tenga sentido decir que
i--
es más rápido quei++
en JavaScript.En primer lugar , depende totalmente de la implementación del motor de JavaScript.
En segundo lugar , siempre que las construcciones más simples se JIT'E y traduzcan a instrucciones nativas, luego
i++
vsi--
dependerá totalmente de la CPU que lo ejecute. Es decir, en los ARM (teléfonos móviles) es más rápido bajar a 0 ya que la disminución y la comparación con cero se ejecutan en una sola instrucción.Probablemente, pensaste que uno era más malo que el otro porque la forma sugerida es
pero la forma sugerida no es porque uno sea más rápido que el otro, sino simplemente porque si escribes
luego en cada iteración
array.length
tenía que ser evaluada (un motor JavaScript más inteligente tal vez podría descubrir que el bucle no cambiará la longitud de la matriz). A pesar de que parece una declaración simple, en realidad es una función que el motor de JavaScript llama bajo el capó.La otra razón, por qué
i--
podría considerarse "más rápido" es porque el motor de JavaScript necesita asignar solo una variable interna para controlar el bucle (variable alvar i
). Si lo comparó con array.length o con alguna otra variable, entonces tenía que haber más de una variable interna para controlar el ciclo, y el número de variables internas es un activo limitado de un motor de JavaScript. Cuantas menos variables se usen en un bucle, más posibilidades tiene JIT de optimización. Es por esoi--
podría considerarse más rápido ...fuente
array.length
se evalúa. La longitud no se calcula cuando se refiere a ella. (Es solo una propiedad que se establece cada vez que se crea o cambia un índice de matriz ). Cuando hay un costo adicional, es porque el motor JS no ha optimizado la cadena de búsqueda para ese nombre.getLength(){return m_length; }
porque hay algo de limpieza involucrada. Pero si intenta pensar al revés: sería bastante ingenioso escribir una implementación de matriz donde la longitud debería calcularse realmente :)length
debe actualizarse inmediatamente cuando se añade o se cambia una propiedad-que-es-un-array-index.dec/jnz
vsinc eax / cmp eax, edx / jne
.Como ninguna de las otras respuestas parece responder a su pregunta específica (más de la mitad de ellas muestran ejemplos de C y discuten lenguajes de nivel inferior, su pregunta es para JavaScript) Decidí escribir la mía.
Entonces, aquí tienes:
Respuesta simple:
i--
generalmente es más rápido porque no tiene que ejecutar una comparación con 0 cada vez que se ejecuta, los resultados de las pruebas en varios métodos están a continuación:Resultados de la prueba: como "probado" por este jsPerf,
arr.pop()
es en realidad el ciclo más rápido con diferencia. Sin embargo, se centra en--i
,i--
,i++
y++i
como lo pidió en su pregunta, aquí están jsPerf (que son de múltiples jsPerf de, consulte fuentes abajo) resultados resumidos:--i
yi--
son iguales en Firefox mientras quei--
es más rápido en Chrome.En Chrome, un bucle básico para (
for (var i = 0; i < arr.length; i++)
) es más rápido que,i--
y--i
mientras que en Firefox es más lento.En Chrome y Firefox un caché
arr.length
es significativamente más rápido con Chrome por delante en aproximadamente 170,000 operaciones / seg.Sin una diferencia significativa,
++i
es más rápido quei++
en la mayoría de los navegadores, AFAIK, nunca es al revés en ningún navegador.Resumen más corto:
arr.pop()
es el ciclo más rápido con diferencia; para los bucles específicamente mencionados,i--
es el bucle más rápido.Fuentes: http://jsperf.com/fastest-array-loops-in-javascript/15 , http://jsperf.com/ipp-vs-ppi-2
Espero que esto responda tu pregunta.
fuente
pop
prueba parece bastante rápida porque está reduciendo el tamaño de la matriz a 0 para la mayoría del ciclo, por lo que puedo decir. Sin embargo, para asegurarme de que las cosas sean justas, he diseñado este jsperf para crear la matriz de la misma manera con cada prueba, que parece.shift()
ser el ganador de mis pocos navegadores, aunque no es lo que esperaba :) jsperf.com / compare-different-types-of-looping++i
: DDepende de la ubicación de su matriz en la memoria y la proporción de aciertos de las páginas de memoria mientras accede a esa matriz.
En algunos casos, el acceso a los miembros de la matriz en el orden de las columnas es más rápido que el orden de las filas debido al aumento en la proporción de aciertos.
fuente
La última vez que me molesté fue cuando escribí el ensamblaje 6502 (¡8 bits, sí!). La gran ganancia es que la mayoría de las operaciones aritméticas (especialmente los decrementos) actualizan un conjunto de indicadores, uno de ellos era
Z
el indicador de "cero alcanzado".Entonces, al final del ciclo, acabas de hacer dos instrucciones:
DEC
(decrementar) yJNZ
(saltar si no es cero), ¡no se necesita comparación!fuente
i--
vsi++
es que con el primero no se introducen variables de control adicionales en el alcance del bucle. Vea mi respuesta a continuación ...dec/jnz
en lugar deinc/cmp/jne
para el caso x86. No verá un ciclo vacío correr más rápido (ambos saturarán el rendimiento de la rama), pero la cuenta regresiva reduce ligeramente la sobrecarga del ciclo. Los buscadores actuales de Intel HW tampoco se molestan por los patrones de acceso a la memoria que van en orden descendente, tampoco. Las CPU más antiguas creo que podrían rastrear como 4 transmisiones hacia atrás y 6 o 10 transmisiones hacia adelante, IIRC.Puede explicarse mediante JavaScript (y todos los idiomas) que eventualmente se convierten en códigos de operación para ejecutarse en la CPU. Las CPU siempre tienen una sola instrucción para comparar contra cero, que es muy rápido.
Por otro lado, si puede garantizar
count
que siempre es así>= 0
, puede simplificar para:fuente
Esto no depende del signo
--
o++
, pero depende de las condiciones que aplique en el bucle.Por ejemplo: su ciclo es más rápido si la variable tiene un valor estático que si su ciclo verifica las condiciones cada vez, como la longitud de una matriz u otras condiciones.
Pero no se preocupe por esta optimización, porque esta vez su efecto se mide en nanosegundos.
fuente
for(var i = array.length; i--; )
No es mucho más rápido. Pero cuando reemplazaarray.length
consuper_puper_function()
, eso puede ser significativamente más rápido (ya que se llama en cada iteración). Esa es la diferencia.Si va a cambiarlo en 2014, no necesita pensar en la optimización. Si va a cambiarlo con "Buscar y reemplazar", no necesita pensar en la optimización. Si no tiene tiempo, no necesita pensar en la optimización. Pero ahora, tienes tiempo para pensarlo.
PD:
i--
no es más rápido quei++
.fuente
Para abreviar: no hay absolutamente ninguna diferencia en hacer esto en JavaScript.
En primer lugar, puede probarlo usted mismo:
jsperf: es una excelente plataforma para todo tipo de pruebas de rendimiento en JavaScript .
http://jsperf.com/inc-vs-dec-2
No solo puede probar y ejecutar cualquier secuencia de comandos en cualquier biblioteca de JavaScript, sino que también tiene acceso a la gran cantidad de secuencias de comandos escritas previamente, así como la capacidad de ver las diferencias entre el tiempo de ejecución en diferentes navegadores en diferentes plataformas.
Por lo que puedes ver, no hay diferencia entre el rendimiento en ningún entorno.
Si desea mejorar el rendimiento de su script, cosas que puede intentar hacer:
var a = array.length;
declaración para que no calcule su valor cada vez en el cicloPero debe comprender que la mejora que puede obtener será tan insignificante que, sobre todo, no debería preocuparse por ello.
Mi propia opinión de por qué apareció una idea tan errónea (Dec vs Inc)
Hace mucho, mucho tiempo había una instrucción de máquina común, DSZ (Decremento y Salto en cero). Las personas que programaron en lenguaje ensamblador utilizaron esta instrucción para implementar bucles con el fin de guardar un registro. Ahora, estos hechos antiguos son obsoletos, y estoy bastante seguro de que no obtendrá ninguna mejora de rendimiento en ningún idioma utilizando esta pseudo mejora.
Creo que la única forma en que dicho conocimiento puede propagarse en nuestro tiempo es cuando lees el código de otra persona. Vea tal construcción y pregunte por qué se implementó y aquí la respuesta: "mejora el rendimiento porque se compara con cero". Te sorprendiste de un mayor conocimiento de tu colega y piensas usarlo para ser mucho más inteligente :-)
fuente
array.length
no necesariamente conlleva una penalización de rendimiento, simplemente porque la máquina virtual JS es lo suficientemente inteligente como para descubrir si la matriz no es modificada por el cuerpo del bucle. Vea mi respuesta a continuación.Hice una comparación en jsbench .
Como señaló alestani, una cosa que lleva tiempo en los bucles ascendentes es evaluar, para cada iteración, el tamaño de su matriz. En este bucle:
evalúa
.length
cada vez que incrementai
. En este:evalúa
.length
solo una vez, cuando declarai
. En este:la comparación es implícita, ocurre justo antes de disminuir
i
, y el código es muy legible. Sin embargo, lo que puede marcar una gran diferencia es lo que se pone dentro del bucle.Bucle con llamada a la función (definido en otra parte):
Bucle con código en línea:
Si puede insertar su código en línea, en lugar de llamar a una función, sin sacrificar la legibilidad, ¡puede tener un bucle de un orden de magnitud más rápido!
Nota : como el navegador se está volviendo bueno para incluir funciones simples, realmente depende de qué tan complejo sea su código. Entonces, perfil antes de optimizar, porque
Pero recuerda:
fuente
La forma en que lo estás haciendo ahora no es más rápida (además de ser un ciclo indefinido, supongo que querías hacerlo)
i--
.Si quieres hacerlo más rápido, haz lo siguiente:
por supuesto, no lo notarías en un bucle tan pequeño. La razón por la que es más rápido es porque está disminuyendo i mientras verifica que es "verdadero" (se evalúa como "falso" cuando llega a 0)
fuente
(i = 10; i--;)
A veces, hacer algunos cambios menores en la forma en que escribimos nuestro código puede marcar una gran diferencia en la rapidez con la que nuestro código se ejecuta realmente. Un área donde un cambio de código menor puede hacer una gran diferencia en los tiempos de ejecución es donde tenemos un bucle for que procesa una matriz. Cuando la matriz es de elementos en la página web (como botones de radio), el cambio tiene el mayor efecto, pero vale la pena aplicar este cambio incluso cuando la matriz es interna al código Javascript.
La forma convencional de codificar un bucle for para procesar una matriz es así:
El problema con esto es que evaluar la longitud de la matriz usando myArray.length lleva tiempo y la forma en que hemos codificado el ciclo significa que esta evaluación debe realizarse cada vez que se realiza el ciclo. Si la matriz contiene 1000 elementos, la longitud de la matriz se evaluará 1001 veces. Si estuviéramos mirando los botones de radio y tuviéramos myForm.myButtons.length, entonces tomará aún más tiempo evaluarlo, ya que el grupo apropiado de botones dentro del formulario especificado debe ubicarse primero antes de que la longitud pueda evaluarse cada vez alrededor del ciclo.
Obviamente, no esperamos que la longitud de la matriz cambie mientras la procesamos, por lo que todos estos nuevos cálculos de la longitud solo se agregan innecesariamente al tiempo de procesamiento. (Por supuesto, si tiene código dentro del bucle que agrega o elimina entradas de matriz, entonces el tamaño de la matriz puede cambiar entre iteraciones y, por lo tanto, no podemos cambiar el código que lo prueba)
Lo que podemos hacer para corregir esto para un ciclo donde el tamaño es fijo es evaluar la longitud una vez al comienzo del ciclo y guardarlo en una variable. Luego podemos probar la variable para decidir cuándo terminar el ciclo. Esto es mucho más rápido que evaluar la longitud de la matriz cada vez, particularmente cuando la matriz contiene más que unas pocas entradas o es parte de la página web.
El código para hacer esto es:
Por lo tanto, ahora solo evaluamos el tamaño de la matriz una vez y probamos nuestro contador de bucle contra la variable que contiene ese valor cada vez alrededor del bucle. Se puede acceder a esta variable adicional mucho más rápido que evaluar el tamaño de la matriz, por lo que nuestro código se ejecutará mucho más rápido que antes. Solo tenemos una variable adicional en nuestro script.
A menudo, no importa en qué orden procesemos la matriz siempre que se procesen todas las entradas de la matriz. Si este es el caso, podemos hacer que nuestro código sea un poco más rápido eliminando la variable adicional que acabamos de agregar y procesando la matriz en orden inverso.
El código final que procesa nuestra matriz de la manera más eficiente posible es:
Este código todavía solo evalúa el tamaño de la matriz una vez al comienzo, pero en lugar de comparar el contador de bucle con una variable, lo comparamos con una constante. Dado que una constante es aún más efectiva para acceder que una variable y dado que tenemos una declaración de asignación menos que antes, nuestra tercera versión del código ahora es ligeramente más eficiente que la segunda versión y mucho más eficiente que la primera.
fuente
++
vs.--
no importa porque JavaScript es un lenguaje interpretado, no un lenguaje compilado. Cada instrucción se traduce a más de un lenguaje de máquina y no debe preocuparse por los detalles sangrientos.Las personas que están hablando de usar
--
(o++
) para hacer un uso eficiente de las instrucciones de montaje están equivocadas. Estas instrucciones se aplican a la aritmética de enteros y no hay enteros en JavaScript, solo números .Deberías escribir código legible.
fuente
En muchos casos, esto no tiene esencialmente nada que ver con el hecho de que los procesadores pueden comparar a cero más rápido que otras comparaciones.
Esto se debe a que solo unos pocos motores Javascript (los que están en la lista JIT) realmente generan código de lenguaje de máquina.
La mayoría de los motores de Javascript crean una representación interna del código fuente que luego interpretan (para tener una idea de cómo es esto, eche un vistazo cerca de la parte inferior de esta página en SpiderMonkey de Firefox ). Generalmente, si un código hace prácticamente lo mismo pero conduce a una representación interna más simple, se ejecutará más rápido.
Tenga en cuenta que con tareas simples como sumar / restar una de una variable, o comparar una variable con algo, la sobrecarga del intérprete que se mueve de una "instrucción" interna a la siguiente es bastante alta, por lo que las "instrucciones" menos son utilizado internamente por el motor JS, mejor.
fuente
Bueno, no sé acerca de JavaScript, realmente debería ser solo una cuestión de reevaluación de la longitud de la matriz y tal vez algo que ver con las matrices asociativas (si solo disminuye, es poco probable que sea necesario asignar nuevas entradas, si la matriz es densa, es decir, alguien puede optimizar para eso).
En el ensamblaje de bajo nivel, hay una instrucción de bucle, llamada DJNZ (decremento y salto si no es cero). Por lo tanto, el decremento y el salto son todos en una sola instrucción, lo que posiblemente sea un poco más rápido que INC y JL / JB (incremento, salto si es menor que / salto si es inferior). Además, comparar con cero es más simple que comparar con otro número. Pero todo eso es realmente marginal y también depende de la arquitectura de destino (podría hacer la diferencia, por ejemplo, en Arm en un teléfono inteligente).
No esperaría que estas diferencias de bajo nivel tengan un impacto tan grande en los idiomas interpretados, simplemente no he visto DJNZ entre las respuestas, así que pensé en compartir un pensamiento interesante.
fuente
DJNZ
es una instrucción en el 8051 (z80) ISA. x86 tiene endec/jnz
lugar deinc/cmp/jne
, y aparentemente arm tiene algo similar. Estoy bastante seguro de que esta no es la causa de la diferencia de Javascript; eso es por tener más para evaluar en la condición de bucle.Se solía decir que --i era más rápido (en C ++) porque solo hay un resultado, el valor disminuido. i-- necesita almacenar el valor disminuido nuevamente en i y también conservar el valor original como resultado (j = i--;). En la mayoría de los compiladores, esto usó dos registros en lugar de uno, lo que podría causar que otra variable tenga que escribirse en la memoria en lugar de retenerse como una variable de registro.
Estoy de acuerdo con los otros que han dicho que no hay diferencia en estos días.
fuente
En palabras muy simples
"i-- e i ++. En realidad, ambos toman el mismo tiempo".
pero en este caso cuando tiene una operación incremental ... el procesador evalúa .length cada vez que la variable se incrementa en 1 y en caso de disminución ... particularmente en este caso, evaluará .length solo una vez hasta que obtengamos 0.
fuente
Primero,
i++
yi--
tome exactamente el mismo tiempo en cualquier lenguaje de programación, incluido JavaScript.El siguiente código lleva un tiempo muy diferente.
Rápido:
Lento:
Por lo tanto, el siguiente código también lleva un tiempo diferente.
Rápido:
Lento:
PS Slow es lento solo para algunos idiomas (motores de JavaScript) debido a la optimización del compilador. La mejor manera es usar '<' en su lugar '<=' (o '=') y '--i' en lugar de 'i--' .
fuente
I-- o i ++ no consumen mucho tiempo. Si profundiza en la arquitectura de la CPU,
++
es más rápido que el--
, ya que la--
operación hará el complemento de 2, pero sucede dentro del hardware, por lo que será más rápido y no se considerará ninguna diferencia importante entre las operaciones++
y--
estas operaciones. menos tiempo consumido en la CPU.El bucle for se ejecuta así:
<
,>
,<=
, etc.Entonces,
calculará la longitud de la matriz solo una vez al inicio y esto no es mucho tiempo, pero
calculará la longitud en cada bucle, por lo que consumirá mucho tiempo.
fuente
var i = Things.length - 1; i >= 0; i--
calculará la longitud 1 vez también.--
operación hará el complemento de 2", pero supongo que significa que negará algo. No, no niega nada en ninguna arquitectura. Restar 1 es tan simple como sumar 1, solo haces un circuito que toma prestado en lugar de llevar.El mejor enfoque para responder a este tipo de preguntas es intentarlo. Configure un bucle que cuente un millón de iteraciones o lo que sea, y hágalo en ambos sentidos. Mida el tiempo de ambos bucles y compare los resultados.
La respuesta probablemente dependerá del navegador que esté utilizando. Algunos tendrán resultados diferentes que otros.
fuente
Me encanta, muchas marcas, pero no hay respuesta: D
En pocas palabras, una comparación contra cero siempre es la comparación más rápida
Entonces (a == 0) en realidad es más rápido al devolver True que (a == 5)
Es pequeño e insignificante y con 100 millones de filas en una colección es medible.
es decir, en un bucle hacia arriba, podría estar diciendo donde i <= array.length e incrementar i
en un bucle hacia abajo, podría estar diciendo donde i> = 0 y disminuir en su lugar i.
La comparación es más rápida. No es la "dirección" del bucle.
fuente
AYUDE A OTROS A EVITAR UN DOLOR DE CABEZA --- ¡VOTE ESTO!
La respuesta más popular en esta página no funciona para Firefox 14 y no pasa el jsLinter. Los bucles "while" necesitan un operador de comparación, no una asignación. Funciona en cromo, safari e incluso es decir. Pero muere en Firefox.
¡ESTO ESTÁ DESCOMPUESTO!
¡ESTO FUNCIONARÁ! (funciona en firefox, pasa el jsLinter)
fuente
while (i--)
y que funcionan en muchos navegadores. ¿Podría haber habido algo extraño en tu prueba? ¿Estaba utilizando una versión beta de Firefox 14?Esto es solo una suposición, pero tal vez sea porque es más fácil para el procesador comparar algo con 0 (i> = 0) en lugar de con otro valor (i <Things.length).
fuente