¿Son los bucles realmente más rápidos en reversa?


He oído esto bastantes veces. ¿Son los bucles JavaScript realmente más rápidos al contar hacia atrás? Si es así, ¿por qué? He visto algunos ejemplos de suite de prueba que muestran que los bucles invertidos son más rápidos, pero no puedo encontrar ninguna explicación de por qué!

Asumo que es porque el bucle ya no tiene que evaluar una propiedad cada vez que comprueba si está terminada y solo comprueba contra 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.
}
Author: Anders, 2009-08-27

30 answers

No es que i-- sea más rápido que i++. En realidad, ambos son igual de rápidos.

Lo que toma tiempo en bucles ascendentes es evaluar, para cada i, el tamaño de su matriz. En este bucle:

for(var i = array.length; i--;)

Evalúas .length solo una vez, cuando declaras i, mientras que para este bucle

for(var i = 1; i <= array.length; i++)

Evalúas .length cada vez que incrementas i, cuando compruebas si i <= array.length.

En la mayoría de los casos, ni siquiera debería preocuparse por este tipo de optimización.

 849
Author: alestanis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-30 00:59:14

Este tipo comparó muchos bucles en javascript, en muchos navegadores. También tiene un conjunto de pruebas para que pueda ejecutarlas usted mismo.

En todos los casos (a menos que me haya perdido uno en mi lectura) el bucle más rápido fue:

var i = arr.length; //or 10
while(i--)
{
  //...
}
 188
Author: Tom Ritter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-13 14:08:41

Intento dar un panorama amplio con esta respuesta.

Los siguientes pensamientos entre paréntesis eran mi creencia hasta que recientemente he probado el tema:

[[En términos de idiomas 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 tanto la optimización, podrías ir ++i en lugar de i++, porque ++i es un comando de procesador único, mientras que i++ significa j=i+1, i=j.]]

Los bucles realmente rápidos se pueden hacer desenrollándolos:

for(i=800000;i>0;--i)
    do_it(i);

Puede ser mucho más lento que

for(i=800000;i>0;i-=8)
{
    do_it(i); do_it(i-1); do_it(i-2); ... do_it(i-7);
}

Pero las razones de 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 como pediste, puedes optimizar las cosas si confías en bibliotecas, funciones integradas para bucles. Deja que ellos decidan cómo se hace mejor.

En consecuencia, en JavaScript, sugeriría usar algo como

array.forEach(function(i) {
    do_it(i);
});

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 redefinir la función forEach (navegador dependiente) para que utilice el último mejor truco! :) @A. M. K. dice que en casos especiales vale la pena en lugar de usar array.pop o array.shift. Si haces eso, ponlo detrás de la cortina. El extremo overkill es agregar opciones a forEach para seleccionar el algoritmo de bucle.]

Además, también para lenguajes de bajo nivel, la mejor práctica es usar alguna función de biblioteca inteligente para operaciones complejas y en bucle si es posible.

Esas bibliotecas también pueden poner cosas (multi-threaded) detrás de su espalda y también los programadores especializados los mantienen actualizados.

Hice un poco más escrutinio y resulta que en C/C++, incluso para 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.)
Así que --i pasa a ser más bien una cosa "elegante". Sólo te hace parecer un mejor programador. :)

Por otro lado, para-desenrollar en esta situación 5e9, tiene me llevó de 12 segundos a 2.5 segundos cuando fui por 10s, y a 2.1 segundos cuando fui por 20s. Fue sin optimización, y la optimización ha reducido las cosas a poco tiempo inconmensurable. :) (El desenrollamiento se puede hacer a mi manera arriba o usando i++, pero eso no trae las cosas por delante en JavaScript. )

En resumen: mantener i--/i++ y ++i/i++ diferencias con las entrevistas de trabajo, se adhieren a array.forEach u otras funciones complejas de la biblioteca cuando estén disponibles. ;)

 127
Author: Barnabas Szabolcs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-19 17:49:49

i-- es tan rápido como i++

Este código es tan rápido como el tuyo, pero usa una variable adicional:

var up = Things.length;
for (var i = 0; i < up; i++) {
    Things[i]
};

La recomendación es NO evaluar el tamaño del array cada vez. Para matrices grandes se puede ver la degradación del rendimiento.

 34
Author: sainiuc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-30 10:21:34

Dado que estás interesado en el tema, echa un vistazo a la publicación de Greg Reimer en el weblog sobre un punto de referencia de bucle JavaScript, ¿Cuál es la Forma más rápida de Codificar un Bucle en JavaScript?:

Construí un conjunto de pruebas de benchmarking de bucles para diferentes formas de codificar bucles en JavaScript. Ya hay algunos de estos por ahí, pero no encontré ninguno que reconociera la diferencia entre los arrays nativos y las colecciones HTML.

También puedes hacer un 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 ejemplo, NoScript).

EDITAR:

Un benchmark 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:

var i, result = 0;
for (i = steps - 1; i; i--) {
  result += i;
}

Como el más rápido precedido por:

var result = 0;
for (var i = steps - 1; i >= 0; i--) {
  result += i;
}

Ejemplo de Benchmark.

 21
Author: dreamcrash,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-15 03:47:26

No Es el -- o ++, es la operación de comparación. Con -- puedes usar una comparación con 0, mientras que con ++ necesitas compararla 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

a++
test (a-length)

Por lo que toma más tiempo en el procesador cuando se compila.

 19
Author: Dr BDO Adams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-19 17:37:02

Respuesta corta

Para código normal, especialmente en un lenguaje de alto nivel como JavaScript, no hay diferencia de rendimiento en i++ y i--.

El criterio de rendimiento es el uso en el bucle for y la instrucción compare.

Esto se aplica a todos los lenguajes de alto nivel y es en su mayoría independiente del uso de JavaScript. La explicación es el código resultante del ensamblador en la línea de fondo.

Detallado explicación

Una diferencia de rendimiento puede ocurrir en un bucle. El fondo es que en el nivel código ensamblador se puede ver que un compare with 0 es solo una instrucción que no necesita un registro adicional.

Esta comparación se emite en cada paso del bucle y puede resultar en una mejora medible del rendimiento.

for(var i = array.length; i--; )

Será evaluado a un pseudo código así:

 i=array.length
 :LOOP_START
 decrement i
 if [ i = 0 ] goto :LOOP_END
 ... BODY_CODE
 :LOOP_END

Tenga en cuenta que 0 es un literal, o en otras palabras, un valor constante.

for(var i = 0 ; i < array.length; i++ )

Se evaluará a un pseudo código como este (se supone una optimización normal del intérprete):

 end=array.length
 i=0
 :LOOP_START
 if [ i < end ] goto :LOOP_END
 increment i
 ... BODY_CODE
 :LOOP_END

Tenga en cuenta que endes una variable que necesita un registro CPU. Esto puede invocar un intercambio de registros adicional en el código y necesita una instrucción más cara compare en la instrucción if.

Solo mis 5 centavos

Para un lenguaje de alto nivel, legibilidad, que facilita mantenibilidad, es más importante como una mejora de rendimiento menor.

Normalmente la iteración clásica del array de principio a fin es mejor.

La iteración más rápida de array end to start resulta en la posible secuencia inversa no deseada.

Post scriptum

Como se preguntó en un comentario: La diferencia de --i y i-- está en la evaluación de i antes o después del decremento.

La mejor explicación es para probarlo; -) Aquí hay un ejemplo de Bash .

 % i=10; echo "$((--i)) --> $i"
 9 --> 9
 % i=10; echo "$((i--)) --> $i"
 10 --> 9
 16
Author: H.-Dirk Schmitt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-19 18:14:02

He visto la misma recomendación en Sublime Text 2.

Como ya se ha dicho, la principal mejora no es evaluar la longitud de la matriz en cada iteración en el bucle for. Esta es una técnica de optimización conocida y particularmente eficiente en JavaScript cuando el array es parte del documento HTML (haciendo un for para todos los elementos li).

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 donde estoy parado, el la principal mejora en la forma en su pregunta es el hecho de que no declara una variable adicional (len en mi ejemplo)

Pero si me preguntas, el punto no es sobre la optimización i++ vs i--, sino sobre no tener que evaluar la longitud de la matriz en cada iteración (puede ver una prueba de referencia en jsperf).

 15
Author: BBog,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-31 10:10:02

No creo que tenga sentido decir que i-- es más rápido que i++ en JavaScript.

En primer lugar , depende totalmente de la implementación del motor JavaScript.

En segundo lugar , siempre que las construcciones más simples JIT'ed y traducidas a instrucciones nativas, entonces i++ vs i-- dependerán totalmente de la CPU que las ejecute. Es decir, en los brazos (teléfonos móviles) es más rápido bajar a 0 ya que decremento y comparar a cero se ejecutan en un solo instrucción.

Probablemente, pensaste que uno era más derrochador que el otro porque la forma sugerida es

for(var i = array.length; i--; )

Pero la forma sugerida no es porque uno sea más rápido que el otro, sino simplemente porque si escribes{[11]]}

for(var i = 0; i < array.length; i++)

Luego en cada iteración array.length tuvo que ser evaluado (motor JavaScript más inteligente tal vez podría averiguar que el bucle no cambiará la longitud de la matriz). A pesar de que parece una declaración simple, en realidad es alguna función que se llama bajo el capó por el motor JavaScript.

La otra razón por la que i-- podría considerarse "más rápido" es porque el motor JavaScript necesita asignar solo una variable interna para controlar el bucle (variable a la var i). Si se compara con la matriz.longitud o a alguna otra variable, entonces tenía que haber más de una variable interna para controlar el bucle, y el número de variables internas son activos limitados de un motor JavaScript. Cuantas menos variables se utilicen en un bucle, más posibilidades tendrá JIT para optimización. Es por eso que i-- podría considerarse más rápido...

 14
Author: Pavel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-08 19:54:14

Dado que ninguna de las otras respuestas parecen responder a su pregunta específica (más de la mitad de ellas muestran ejemplos de C y discuten idiomas de nivel inferior, su pregunta es para JavaScript) Decidí escribir la mía propia.

Así que, aquí tienes: {[18]]}

Respuesta simple: i-- es generalmente más rápido porque no tiene que ejecutar una comparación con 0 cada vez que se ejecuta, los resultados de la prueba en varios métodos están a continuación:

Resultados de la prueba: Como "probado" por este jsPerf, arr.pop() es en realidad el bucle más rápido con diferencia. Pero, centrándose en --i, i--, i++ y ++i como usted hizo en su pregunta, aquí están los resultados resumidos de jsPerf (son de múltiples jsPerf, por favor vea las fuentes a continuación):

--i y i-- son los mismos en Firefox, mientras que i-- es más rápido en Chrome.

En Chrome un bucle for básico (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.

Tanto en Chrome y Firefox un cached arr.length es significativamente más rápido con Chrome por delante por cerca de 170,000 ops / seg.

Sin una diferencia significativa, ++i es más rápido que i++ en la mayoría de los navegadores, AFAIK, nunca es al revés en cualquier navegador.

Resumen más breve: arr.pop() es el bucle 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

I espero que esto responda a su pregunta.

 14
Author: A.M.K,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-25 19:50:16

Depende de la colocación de su matriz en la memoria y la proporción de visitas de las páginas de memoria mientras accede a esa matriz.

En algunos casos, el acceso a los miembros de la matriz en orden de columna es más rápido que el orden de fila debido al aumento en la proporción de visitas.

 13
Author: Akbar Bayati,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-12 12:55:47

La última vez que me preocupé fue cuando escribí 6502 montaje (8-bit, yeah!). La gran ganancia es que la mayoría de las operaciones aritméticas (especialmente decrementos) actualizan un conjunto de banderas, una de ellas era Z, el indicador 'alcanzado cero'.

Por lo tanto, al final del bucle que acaba de hacer dos instrucciones: DEC (decrementar) y JNZ (saltar si no es cero), no se necesita comparación!

 11
Author: Javier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-19 17:55:16

Para abreviar: No hay absolutamente ninguna diferencia en hacer esto en JavaScript.

En primer lugar, puede probarlo usted mismo:

No solo puede probar y ejecutar cualquier script en cualquier biblioteca JavaScript, sino que también tiene acceso a un montón de scripts escritos anteriormente, así como la capacidad de ver las diferencias entre el tiempo de ejecución en diferentes navegadores en diferentes plataformas.

Por lo que se puede ver, no hay diferencia entre el rendimiento en cualquier entorno.

Si desea mejorar el rendimiento de su script, cosas que puede intentar hacer:

  1. Tenga una instrucción var a = array.length; para que no calcule su valor cada vez en el bucle
  2. Hacer loop desenrollado http://en.wikipedia.org/wiki/Loop_unwinding

Pero tienes que entender que la mejora que puedes obtener será tan insignificante, que en su mayoría ni siquiera debería importarte.

Mi propia opinión por qué tal idea errónea (Dec vs Inc) apareció

Hace mucho, mucho tiempo había una instrucción de máquina común, DSZ (Decrement and Skip on Zero). Las personas que programaron en lenguaje ensamblador usaron esta instrucción para implementar bucles con el fin de registrar. Ahora bien, estos hechos antiguos son obsoletos, y estoy bastante seguro de que no obtendrás ninguna mejora de rendimiento en ningún idioma usando esta pseudo mejora.

Creo que la única manera en que tal 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 desconcertaste del conocimiento superior de tu colega y piensas usarlo para ser mucho más inteligente: -)

 8
Author: Salvador Dali,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-19 18:04:47

Puede explicarse por JavaScript (y todos los lenguajes) que eventualmente se convierten en opcodes para ejecutarse en la CPU. Las CPU siempre tienen una sola instrucción para comparar con cero, lo cual es muy rápido.

Como un aparte, si usted puede garantizar count es siempre >= 0, usted podría simplificar a:

for (var i = count; i--;)
{
  // whatever
}
 7
Author: searlea,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-27 11:58:14

Esto no depende del signo -- o ++, pero depende de las condiciones que aplique en el bucle.

Por ejemplo: Su bucle es más rápido si la variable tiene un valor estático que si su bucle comprueba 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.

 7
Author: Arvind Kanjariya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-19 17:52:06

for(var i = array.length; i--; ) no es mucho más rápido. Pero cuando reemplazas array.length con super_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 tienes tiempo, no necesitas pensar en la optimización. Pero ahora, tienes tiempo para pensarlo.

P.d.: i-- no es más rápido que i++.

 7
Author: Dmitry Isaev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-19 17:53:57

A veces hacer algunos cambios muy pequeños en la forma en que escribimos nuestro código puede hacer una gran diferencia en la rapidez con la que se ejecuta realmente nuestro código. 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 está procesando una matriz. Donde la matriz es de elementos en la página web (como botones de radio) el cambio tiene el mayor efecto, pero todavía vale la pena aplicar este cambio incluso donde la matriz es interna al Javascript codificar.

La forma convencional de codificar un bucle for para procesar un array lis es así:

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

El problema con esto es que la evaluación de la longitud de la matriz utilizando myArray.la longitud lleva tiempo y la forma en que hemos codificado el bucle significa que esta evaluación debe realizarse cada vez alrededor del bucle. Si el array contiene 1000 elementos entonces la longitud del array será evaluada 1001 veces. Si estuviéramos mirando botones de radio y tuviéramos myForm.Mis botones.longitud entonces él tomará aún más tiempo evaluar ya que el grupo apropiado de botones dentro de la forma especificada primero debe ser localizado antes de que la longitud pueda ser evaluada cada vez alrededor del bucle.

Obviamente no esperamos que la longitud de la matriz cambie mientras la procesamos, por lo que todos estos recálculos de la longitud solo agregan innecesariamente al tiempo de procesamiento. (Por supuesto, si tiene código dentro del bucle que agrega o elimina entradas de matriz, el tamaño de la matriz puede cambiar entre iteraciones y así no podemos cambiar el código que prueba para ello)

Lo que podemos hacer para corregir esto para un bucle donde el tamaño es fijo es evaluar la longitud una vez al inicio del bucle y guardarlo en una variable. Luego podemos probar la variable para decidir cuándo terminar el bucle. Esto es mucho más rápido que evaluar la longitud de la matriz cada vez, especialmente cuando la matriz contiene más de unas pocas entradas o es parte de la página web.

El código para hacer esto is:

for (var i = 0, var j = myArray.length; i < j; i++) {...

Así que 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 extra en nuestro script.

A menudo no importa en qué orden procesemos la matriz, siempre y cuando todas las entradas de la matriz se procesen. Donde este es el caso podemos hacer nuestro código 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 nuestro array de la manera más eficiente posible es:

for (var i = myArray.length-1; i > -1; i--) {...

Este código todavía solo evalúa el tamaño de la matriz una vez al inicio, pero en lugar de comparar el contador de bucles con una variable, lo comparamos con una constante. Dado que una constante es aún más eficaz para acceder que una variable y ya que tenemos una menos instrucción de asignación que antes de nuestra tercera versión del código es ahora un poco más eficiente que la segunda versión y mucho más eficiente que la primera.

 5
Author: Sid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-31 06:52:08

Hice una comparación en jsbench.

Como señaló alestani, una cosa que toma tiempo en bucles ascendentes, es evaluar, para cada iteración, el tamaño de su matriz. En este bucle:

for ( var i = 1; i <= array.length; i++ )

Evalúas .length cada vez que incrementas i. En este caso:

for ( var i = 1, l = array.length; i <= l; i++ )

Evalúas .length solo una vez, cuando declaras i. En este caso:

for ( var i = array.length; i--; )

La comparación implícita, sucede justo antes de decrecer i, y el código es muy legible. Sin embargo, lo que puede hacer una gran diferencia, es lo que pones dentro del bucle.

Bucle con llamada a la función (definida en otro lugar):

for (i = values.length; i-- ;) {
  add( values[i] );
}

Bucle con código en línea:

var sum = 0;
for ( i = values.length; i-- ;) {
  sum += values[i];
}

Si puede insertar su código, en lugar de llamar a una función, sin sacrificar la legibilidad, ¡puede tener un bucle un orden de magnitud más rápido!


Nota : como el navegador se está volviendo bueno en la inserción de funciones simples, realmente depende de lo complejo tu código lo es. Por lo tanto, el perfil antes de optimizar, porque

  1. El cuello de botella puede estar en otro lugar (ajax, reflow,...)
  2. Usted puede elegir un algoritmo mejor
  3. Puede elegir una mejor estructura de datos

Pero recuerda: {[13]]}

El código está escrito para que la gente lo lea, y solo incidentalmente para que las máquinas lo ejecuten.

 5
Author: Spyryto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-23 12:57:11

La forma en que lo estás haciendo ahora no es más rápida (aparte de ser un bucle indefinido, supongo que querías hacer i--.

Si quieres hacerlo más rápido hacer:

for (i = 10; i--;) {
    //super fast loop
}

Por supuesto que no lo notarías en un bucle tan pequeño. La razón por la que es más rápido es porque estás decrementando i mientras compruebas que es "verdadero" (se evalúa como "falso" cuando llega a 0)

 4
Author: peirix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-27 11:57:44

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 máquina.

La mayoría de los motores Javascript construyen 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 Firefox SpiderMonkey ). Por lo general, si una pieza de 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 agregar/restar una de una variable, o comparar una variable con algo, la sobrecarga del intérprete al pasar de una "instrucción" interna a la siguiente es bastante alta, por lo que cuantas menos "instrucciones" sean usadas internamente por el motor JS, mejor.

 3
Author: Artelius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-08 08:36:26

Bueno, no se sobre JavaScript, realmente debería ser solo una cuestión de re-evaluación de la longitud del array y tal vez algo que ver con los arrays asociativos (si solo decrementas, es poco probable que se deban asignar nuevas entradas - si el array es denso, es decir. alguien puede optimizar para eso).

En el ensamblaje de bajo nivel, hay una instrucción de bucle, llamada DJNZ (decrementar y saltar si no es cero). Así que el decremento y salto es todo en una instrucción, por lo que es posible cada vez 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 gran impacto en los lenguajes interpretados, simplemente no he visto DJNZ entre las respuestas, así que pensé que compartiría un interesante pensamiento.

 3
Author: the swine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-30 12:54:06

usó para decir que i yo era más rápido (en C++) porque solo hay un resultado, el valor decrementado. i needs necesita almacenar el valor decrementado de nuevo en i y también retener el valor original como resultado (j=i;;). En la mayoría de los compiladores esto usaba dos registros en lugar de uno, lo que podría causar que otra variable tuviera que ser escrita en memoria en lugar de retenida como una variable de registro.

Estoy de acuerdo con aquellos otros que han dicho que no hace ninguna diferencia estos jornadas.

 3
Author: Ant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-30 18:09:18

En palabras muy simples

"i++e i++. En realidad, ambos toman el mismo tiempo".

Pero en este caso cuando se tiene una operación incremental.. procesador evaluar el .longitud cada variable de tiempo se incrementa en 1 y en caso de decremento.. particularmente en este caso, se evaluará .longitud solo una vez hasta que tengamos 0.

 3
Author: Ravi_Parmar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-31 11:00:14

++ 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 ensamblaje están equivocadas. Estas instrucciones se aplican a la aritmética de enteros y no hay enteros en JavaScript, solo números.

Usted debe escribir legible codificar.

 3
Author: Salman A,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-31 13:42:47

Primero, i++ y i-- toman exactamente el mismo tiempo en cualquier lenguaje de programación, incluido JavaScript.

El siguiente código toma mucho tiempo diferente.

Rápido:

for (var i = 0, len = Things.length - 1; i <= len; i++) { Things[i] };

Lento:

for (var i = 0; i <= Things.length - 1; i++) { Things[i] };

Por lo tanto, el siguiente código toma un tiempo diferente también.

Rápido:

for (var i = Things.length - 1; i >= 0; i--) { Things[i] };

Lento:

for (var i = 0; i <= Things.length - 1; i++) { Things[i] };

P.D. Slow es lento solo para unos pocos lenguajes (motores JavaScript) debido a la optimización del compilador. La mejor manera es usar ' (or'=') and 'i i' instead 'i {'.

 3
Author: Dmitry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-17 23:39:25

I++o i ++ no consumen mucho tiempo. Si profundiza en la arquitectura de la CPU, ++ es más rápido que --, ya que la operación -- hará el complemento de 2, pero ocurre dentro del hardware, por lo que esto lo hará rápido y no hay una diferencia importante entre ++ y -- también estas operaciones se consideran del menor tiempo consumido en la CPU.

El bucle for se ejecuta así:

  • Inicializar la variable una vez en el empezar.
  • Comprobación de la restricción en el segundo operando del bucle, <, >, <=, etc.
  • Luego aplique el bucle.
  • Incrementa el bucle y vuelve a lanzar estos procesos de nuevo.

Así que,

for (var i = Things.length - 1; i >= 0; i--) {
    Things[i]
}; 

Calculará la longitud de la matriz solo una vez al inicio y esto no es mucho tiempo, pero

for(var i = array.length; i--; ) 

Calculará la longitud en cada bucle, por lo que consumirá mucho tiempo.

 3
Author: Omar Freewan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-19 18:10:27

El mejor enfoque para responder a este tipo de preguntas es realmente probarlo. Configura un bucle que cuente un millón de iteraciones o lo que sea, y hazlo de ambas maneras. Mide el tiempo de ambos bucles y compara los resultados.

La respuesta probablemente dependerá del navegador que esté utilizando. Algunos tendrán resultados diferentes que otros.

 1
Author: Greg Hewgill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-27 11:58:44

Me encanta, muchas marcas pero no hay respuesta: D

Simplemente una comparación contra cero es siempre la comparación más rápida

Así que (a==0) es en realidad más rápido en 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

En un bucle hacia abajo puede estar diciendo donde i > = 0 y estar decrementando i en su lugar.

La comparación es más rápida. No la 'dirección' del bucle.

 1
Author: Robert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-27 12:08:46

AYUDAR 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 chrome, safari, e incluso ie. Pero muere en firefox.

ESTO ESTÁ ROTO!

var i = arr.length; //or 10
while(i--)
{
  //...
}

¡ESTO FUNCIONARÁ! (funciona en Firefox, pasa el jsLinter)

var i = arr.length; //or 10
while(i>-1)
{
  //...
  i = i - 1;
}
 1
Author: mrbinky3000,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-17 17:43:44

Esto es solo una suposición, pero tal vez es porque es más fácil para el procesador comparar algo con 0 ( i >= 0 ) en lugar de con otro valor ( i

 1
Author: Rorchackh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-30 10:13:01