¿Los bucles son realmente más rápidos en reversa?

He escuchado esto bastantes 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 suite de prueba 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 se comprueba para ver si está terminado y simplemente se compara con 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. } 

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

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

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

Usted evalúa .length solo una vez, cuando declara i , mientras que para este ciclo

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

usted evalúa .length cada vez que incrementa i , cuando comprueba si i <= array.length .

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

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

En todos los casos (a menos que perdí uno en mi lectura) el ciclo más rápido fue:

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

Intento dar una visión amplia con esta respuesta.

Los siguientes pensamientos entre corchetes fueron mi creencia hasta que acabo de probar el problema:

[[En términos de lenguajes de bajo nivel como C / C ++ , el código se comstack para que el procesador tenga un comando de salto condicional especial cuando una variable es cero (o no es cero).
Además, si te importa esta optimización, puedes ir ++i 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 para esto pueden ser bastante complicadas (solo para mencionar, hay problemas con el preprocesamiento de comandos del procesador y el manejo del caché en el juego).

En términos de lenguajes de alto nivel , como JavaScript, como preguntas, puedes optimizar cosas si dependes de bibliotecas, funciones integradas para bucles. Déjelos decidir 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 posibilidad de optimizar su código.

[OBSERVACIÓN: no solo los navegadores, sino que también usted tiene un espacio para optimizarlo con facilidad, solo redefina la función forEach (dependiendo del navegador) para que utilice los mejores trucos más recientes. 🙂 @AMK dice que en casos especiales vale la pena usar array.pop o array.shift . Si haces eso, ponlo detrás de la cortina. El exceso excesivo es agregar opciones a forEach para seleccionar el algoritmo de bucle.]

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

Esas bibliotecas también pueden poner cosas (multihilo) a sus espaldas y también los progtwigdores especializados las mantienen actualizadas.

Hice un poco más de escrutinio y resulta que en C / C ++, incluso para 5e9 = (50,000×100,000) operaciones, no hay diferencia entre subir y bajar si las pruebas se realizan 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).
Entonces, sucede que es más bien algo “elegante”. Solo te hace ver como un mejor progtwigdor. 🙂

Por otro lado, para-desenrollarme en esta situación 5e9, me ha bajado de 12 segundos a 2.5 segundos cuando pasé por 10 segundos, y a 2.1 segundos cuando supere los 20 segundos. Fue sin optimización, y la optimización ha reducido las cosas a poco tiempo. 🙂 (El desenrollado se puede hacer a mi manera arriba o usando i++ , pero eso no trae las cosas por delante en JavaScript).

En general: mantenga las i-- / i++ y ++i / i++ en las entrevistas de trabajo, array.forEach a array.forEach u otras funciones complejas de la biblioteca cuando estén disponibles. 😉

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

Este código a continuación es tan rápido como el suyo, 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 de la matriz cada vez. Para arreglos grandes, uno puede ver la degradación del rendimiento.

Ya 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? :

Creé un conjunto de pruebas de benchmarking de bucle para diferentes formas de encoding de bucles en JavaScript. Ya hay algunos de estos, pero no encontré ninguno que reconociera la diferencia entre las matrices nativas y las colecciones de HTML.

También puede realizar una prueba de rendimiento en un ciclo abriendo https://blogs.oracle.com/greimer/resource/loop-test.html (no funciona si JavaScript está bloqueado en el navegador, por ejemplo, NoScript ).

EDITAR:

Se puede realizar un benchmark más reciente creado por Milan Adamovsky 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 ciclo:

 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 referencia.

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 normalmente está disponible, mientras que comparar con un entero finito requiere una resta.

a++ < length

en realidad está comstackdo como

 a++ test (a-length) 

Por lo tanto, lleva más tiempo en el procesador cuando se comstack.

Respuesta corta

Para el 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 statement de comparación .

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

Explicación detallada

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

Esta comparación se emite en cada pasada del ciclo y puede dar como resultado una mejora de rendimiento mensurable.

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

se evaluará a un pseudo código como este:

  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 la 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 el final es una variable que necesita un registro de CPU . Esto puede invocar un intercambio de registro adicional en el código y necesita una statement de comparación más costosa en la statement if .

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 la matriz de principio a fin es mejor.

La iteración más rápida desde el extremo de la matriz hasta el inicio da como resultado la secuencia inversa posiblemente no deseada.

Publicar scriptum

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

La mejor explicación es probarlo 😉 Aquí hay un ejemplo de Bash .

  % i=10; echo "$((--i)) --> $i" 9 --> 9 % i=10; echo "$((i--)) --> $i" 10 --> 9 

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

Al igual que ya se dijo, la mejora principal no es evaluar la longitud de la matriz en cada iteración en el ciclo 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 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, la principal mejora en la forma de 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 (puedes ver una prueba de referencia en jsperf ).

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 de JavaScript.

En segundo lugar , siempre que los constructos más simples JIT hayan sido traducidos a instrucciones nativas, entonces i++ vs i-- dependerá totalmente de la CPU que lo ejecute. Es decir, en ARM (teléfonos móviles) es más rápido bajar a 0 ya que el decremento y la comparación con cero se ejecutan en una sola instrucción.

Probablemente, pensaste que uno era un desperdicio que el otro porque el camino sugerido es

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

pero el camino sugerido no es porque uno más rápido que el otro, sino simplemente porque si escribes

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

luego, en cada array.length iteración, se tuvo que evaluar la longitud (el motor de JavaScript más inteligente quizás podría darse cuenta de que ese ciclo no cambiará la longitud de la matriz). A pesar de que parece una statement simple, en realidad es una función que obtiene el motor de JavaScript.

La otra razón, por la cual i-- podría considerarse "más rápido" es porque el motor de JavaScript necesita asignar solo una variable interna para controlar el ciclo (variable a var i ). Si comparaste 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 utilicen en un bucle, mayor será la probabilidad de que JIT tenga una optimización. Es por eso i-- podría considerarse más rápido ...

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

Entonces, aquí tienes:

Respuesta simple: i-- es generalmente más rápido porque no tiene que ejecutar una comparación a 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 bucle más rápido con diferencia. Pero, centrándose en --i , i-- , i++ y ++i como lo hizo en su pregunta, aquí están jsPerf (son de múltiples jsPerf, consulte las fonts a continuación) resultados resumidos:

--i e i-- son lo mismo en Firefox, mientras que i-- es más rápido en Chrome.

En Chrome, un bucle for ( 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 arr.length almacenado en caché es significativamente más rápido con Chrome por delante en aproximadamente 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 ningún navegador.

Resumen más corto: arr.pop() es el bucle más rápido con diferencia; para los bucles mencionados específicamente, 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.

Depende de la ubicación de su matriz en la memoria y la proporción de aciertos de las páginas de memoria mientras está accediendo 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.

La última vez que me molesté fue cuando escribí el ensamblaje 6502 (8 bits, ¡sí!). La gran ventaja es que la mayoría de las operaciones aritméticas (especialmente decrementos) actualizaron un conjunto de indicadores, uno de ellos era Z , el indicador “llegó a cero”.

Por lo tanto, al final del ciclo simplemente hizo dos instrucciones: DEC (decremento) y JNZ (salto si no es cero), ¡no se necesita comparación!

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 de JavaScript, sino que también tiene acceso a todo el conjunto de scripts escritos previamente, así como la capacidad de ver las diferencias entre el tiempo de ejecución en diferentes navegadores en diferentes plataformas.

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

Si desea mejorar el rendimiento de su script, puede intentar lo siguiente:

  1. Tener un var a = array.length; statement para que no esté calculando su valor cada vez en el ciclo
  2. Do loop larolándose http://en.wikipedia.org/wiki/Loop_unwinding

Pero debes entender que la mejora que puedas obtener será tan insignificante, que en su mayoría ni siquiera deberías preocuparte por ello.

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

Hace mucho, mucho tiempo hubo una instrucción de máquina común, DSZ (Decremento y Saltar en cero). Las personas que progtwigron en lenguaje ensamblador usaron esta instrucción para implementar bucles a fin de guardar un registro. Ahora estos hechos antiguos están obsoletos, y estoy seguro de que no obtendrás ninguna mejora en el rendimiento en ningún idioma con esta pseudo mejora.

Creo que la única forma en que ese conocimiento puede propagarse en nuestro tiempo es cuando lees el código de otra persona. Vea una construcción así y pregunte por qué se implementó y aquí la respuesta: “mejora el rendimiento porque se compara con cero”. Te volviste desconcertado por el mayor conocimiento de tu colega y piensas usarlo para ser mucho más inteligente 🙂

Puede ser explicado por JavaScript (y todos los idiomas) eventualmente convirtiéndose 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.

Como comentario, si puedes garantizar que el count siempre es >= 0 , puedes simplificarlo a:

 for (var i = count; i--;) { // whatever } 

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

Por ejemplo: su ciclo es más rápido si la variable tiene un valor estático que si su ciclo de control estuviera en 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.

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

PD: i-- no es más rápido que 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 se ejecuta nuestro código. Un área donde un cambio de código menor puede marcar una gran diferencia en los tiempos de ejecución es cuando tenemos un bucle for que procesa una matriz. Cuando la matriz contiene elementos en la página web (como botones de opción), el cambio tiene el mayor efecto, pero vale la pena aplicar este cambio incluso cuando la matriz sea interna al código JavaScript.

La forma convencional de codificar un bucle for para procesar una matriz lis de esta manera:

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

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 en todo momento alrededor del ciclo. Si la matriz contiene 1000 elementos, la longitud de la matriz se evaluará 1001 veces. Si estuviéramos mirando botones de opción y hubiéramos tenido myForm.myButtons.length, la evaluación tardará aún más, ya que primero debe ubicarse el grupo apropiado de botones dentro del formulario especificado antes de poder evaluar la longitud cada vez que se pasa el ciclo.

Obviamente, no esperamos que la longitud de la matriz cambie mientras la procesamos, por lo que todos estos cálculos de la longitud solo agregan innecesariamente al tiempo de procesamiento. (Of course if you have code inside the loop that adds or removes array entries then the array size can change between iterations and so we can't change the code that tests for it)

What we can do to correct this for a loop where the size is fixed is to evaluate the length once at the start of the loop and save it in a variable. We can then test the variable to decide when to terminate the loop. This is much faster than evaluating the array length each time particularly when the array contains more than just a few entries or is part of the web page.

The code to do this is:

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

So now we only evaluate the size of the array once and test our loop counter against the variable that holds that value each time around the loop. This extra variable can be accessed much faster than evaluating the size of the array and so our code will run much faster than before. We just have one extra variable in our script.

Often it doesn't matter what order we process the array in as long as all of the entries in the array get processed. Where this is the case we can make our code slightly faster by doing away with the extra variable that we just added and processing the array in reverse order.

The final code that processes our array in the most efficient way possible is:

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

This code still only evaluates the size of the array once at the start but instead of comparing the loop counter with a variable we compare it with a constant. Since a constant is even more effective to access than a variable and since we have one fewer assignment statement than before our third version of the code is now slightly more efficient than the second version and vastly more efficient than the first.

I made a comparison on jsbench .

As alestani pointed out, one thing that takes time in ascending loops, is to evaluate, for each iteration, the size of your array. In this loop:

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

you evaluate .length each time you increment i . In this one:

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

you evaluate .length only once, when you declare i . In this one:

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

the comparison is implicit, it happens just before decrementing i , and the code is very readable. However, what can make a terrific difference, is what you put inside the loop.

Loop with call to function (defined elsewhere):

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

Loop with inlined code:

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

If you can inline your code, instead of calling a function, without sacrificing legibility, you can have a loop an order of magnitude faster!


Note : as browser are becoming good at inlining simple functions, it really depends on how complex your code is. So, profile before optimizing, because

  1. The bottleneck may be elsewhere (ajax, reflow, ...)
  2. You may choose a better algorithm
  3. You may choose a better data structure

But remember:

Code is written for people to read, and only incidentally for machines to execute.

The way you’re doing it now isn’t faster (apart from it being an indefinite loop, I guess you meant to do i-- .

If you want to make it faster do:

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

of course you wouldn’t notice it on such a small loop. The reason it’s faster is because you’re decrementing i while checking that it’s “true” (it evaluates to “false” when it reaches 0)

In many cases, this has essentially nothing to do with the fact that processors can compare to zero faster than other comparisons.

This is because only a few Javascript engines (the ones in the JIT list) actually generate machine language code.

Most Javascript engines build an internal representation of the source code which they then interpret (to get an idea of what this is like, have a look near the bottom of this page on Firefox’s SpiderMonkey ). Generally if a piece of code does practically the same thing but leads to a simpler internal representation, it will run faster.

Bear in mind that with simple tasks like adding/subtracting one from a variable, or comparing a variable to something, the overhead of the interpreter moving from one internal “instruction” to the next is quite high, so the less “instructions” that are used internally by the JS engine, the better.

Well, I don’t know about JavaScript, it should really be just a matter of re-evaluation array length and maybe something to do with the associative arrays (if you only decrement, it is unlikely new entries would need to be allocated – if the array is dense, that is. someone may optimize for that).

In low-level assembly, there is a looping instruction, called DJNZ (decrement and jump if non-zero). So the decrement and jump is all in one instruction, making it possibly ever-so-slightly faster than INC and JL / JB (increment, jump if less than / jump if below). Also, comparing against zero is simpler than comparing against another number. But all that is really marginal and also depends on target architecture (could make difference eg on Arm in a smartphone).

I wouldn’t expect this low-level differences to have so great impact on interpreted languages, I just haven’t seen DJNZ among the responses so I thought I would share an interesting thought.

It used to be said that –i was faster (in C++) because there is only one result, the decremented value. i– needs to store the decremented value back to i and also retain the original value as the result (j = i–;). In most compilers this used up two registers rather than one which could cause another variable to have to be written to memory rather than retained as a register variable.

I agree with those others that have said it makes no difference these days.

In very simple words

“i– and i++. Actually, they’re both takes the same time”.

but in this case when you have incremental operation.. processor evaluate the .length every time variable is incremented by 1 and in case of decrement.. particularly in this case, it will evaluate .length only once till we get 0.

++ vs. -- does not matter because JavaScript is an interpreted language, not a compiled language. Each instruction translates to more than one machine language and you should not care about the gory details.

People who are talking about using -- (or ++ ) to make efficient use of assembly instructions are wrong. These instruction apply to integer arithmetic and there are no integers in JavaScript, just numbers .

You should write readable code.

First, i++ and i-- take exactly the same time on any programming language, including JavaScript.

The following code take much different time.

Fast:

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

Slow:

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

Therefore the following code take different time too.

Fast:

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

Slow:

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

PS Slow is slow only for a few languages (JavaScript engines) because of compiler's optimization. The best way is to use '<' instead '<=' (or '=') and '--i' instead 'i--' .

Not a lot of time is consumed by i– or i++. If you go deep inside the CPU architecture the ++ is more speedy than the -- , since the -- operation will do the 2’s complement, but it happend inside the hardware so this will make it speedy and no major difference between the ++ and -- also these operations are considered of the least time consumed in the CPU.

The for loop runs like this:

  • Initialize the variable once at the start.
  • Check the constraint in the second operand of the loop, < , > , <= , etc.
  • Then apply the loop.
  • Increment the loop and loop again throw these processes again.

Asi que,

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

will calculate the array length only once at the start and this is not a lot of time, but

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

will calculate the length at each loop, so it will consume a lot of time.

The best approach to answering this sort of question is to actually try it. Set up a loop that counts a million iterations or whatever, and do it both ways. Time both loops, and compare the results.

The answer will probably depend on which browser you are using. Some will have different results than others.

Love it, lots of marks up but no answer 😀

Simply put a comparison against zero is always the fastest comparison

So (a==0) is actually quicker at returning True than (a==5)

It’s small and insignificant and with 100 million rows in a collection it’s measurable.

ie on a loop up you might be saying where i <= array.length and be incrementing i

on a down loop you might be saying where i >= 0 and be decrementing i instead.

The comparison is quicker. Not the ‘direction’ of the loop.

HELP OTHERS AVOID A HEADACHE — VOTE THIS UP!!!

The most popular answer on this page does not work for Firefox 14 and does not pass the jsLinter. “while” loops need a comparison operator, not an assignment. It does work on chrome, safari, and even ie. But dies in firefox.

THIS IS BROKEN!

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

THIS WILL WORK! (works on firefox, passes the jsLinter)

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

This is just a guess, but maybe it’s because it’s easier for the processor to compare something with 0 ( i >= 0 ) instead of with another value ( i < Things.length).

Intereting Posts