Lo que su maestro ha dicho fue una declaración oblicua sin mucha aclaración. NO es que decrementar sea más rápido que incrementar, pero puede crear un bucle mucho más rápido con decremento que con incremento.
Sin hablar en detalle sobre esto, sin necesidad de usar un contador de bucle, etc., lo que importa a continuación es solo la velocidad y el conteo de bucles (no cero).
Así es como la mayoría de la gente implementa el bucle con 10 iteraciones:
int i;
for (i = 0; i < 10; i++)
{
//something here
}
Para el 99% de los casos, es todo lo que uno puede necesitar, pero junto con PHP, PYTHON, JavaScript, existe todo un mundo de software crítico (generalmente integrado, SO, juegos, etc.) donde los ticks de la CPU realmente importan, así que mire brevemente el código de ensamblaje de:
int i;
for (i = 0; i < 10; i++)
{
//something here
}
después de la compilación (sin optimización) la versión compilada puede verse así (VS2015):
-------- C7 45 B0 00 00 00 00 mov dword ptr [i],0
-------- EB 09 jmp labelB
labelA 8B 45 B0 mov eax,dword ptr [i]
-------- 83 C0 01 add eax,1
-------- 89 45 B0 mov dword ptr [i],eax
labelB 83 7D B0 0A cmp dword ptr [i],0Ah
-------- 7D 02 jge out1
-------- EB EF jmp labelA
out1:
El ciclo completo tiene 8 instrucciones (26 bytes). En él, en realidad hay 6 instrucciones (17 bytes) con 2 ramas. Sí, sí, sé que se puede hacer mejor (es solo un ejemplo).
Ahora considere esta construcción frecuente que a menudo encontrará escrita por desarrolladores integrados:
i = 10;
do
{
//something here
} while (--i);
También itera 10 veces (sí, sé que el valor es diferente en comparación con el bucle que se muestra, pero aquí nos importa el recuento de iteraciones). Esto se puede compilar en esto:
00074EBC C7 45 B0 01 00 00 00 mov dword ptr [i],1
00074EC3 8B 45 B0 mov eax,dword ptr [i]
00074EC6 83 E8 01 sub eax,1
00074EC9 89 45 B0 mov dword ptr [i],eax
00074ECC 75 F5 jne main+0C3h (074EC3h)
5 instrucciones (18 bytes) y solo una rama. En realidad, hay 4 instrucciones en el bucle (11 bytes).
Lo mejor es que algunas CPU (incluidas las compatibles con x86 / x64) tienen instrucciones que pueden disminuir un registro, luego comparar el resultado con cero y realizar una bifurcación si el resultado es diferente de cero. Prácticamente TODOS los PC cpus implementan esta instrucción. Al usarlo, el bucle es en realidad solo una (sí, una) instrucción de 2 bytes:
00144ECE B9 0A 00 00 00 mov ecx,0Ah
label:
// something here
00144ED3 E2 FE loop label (0144ED3h) // decrement ecx and jump to label if not zero
¿Tengo que explicar cuál es más rápido?
Ahora, incluso si una CPU en particular no implementa la instrucción anterior, todo lo que necesita para emularlo es una disminución seguida de un salto condicional si el resultado de la instrucción anterior es cero.
Entonces, independientemente de algunos casos, puede señalar como un comentario por qué estoy equivocado, etc., etc. DESTACO: SÍ, ES BENEFICIOSO DESPLAZARSE HACIA ABAJO si sabe cómo, por qué y cuándo.
PD. Sí, sé que el compilador inteligente (con el nivel de optimización apropiado) reescribirá para el bucle (con contador de bucle ascendente) en do..mientras equivalente para iteraciones de bucle constantes ... (o desenrollarlo) ...