Ciò che il tuo insegnante ha detto è stata una dichiarazione obliqua senza molti chiarimenti. NON è che il decremento sia più veloce dell'incremento, ma è possibile creare un ciclo molto più veloce con il decremento che con l'incremento.
Senza andare avanti a lungo, senza la necessità di utilizzare il contatore di loop ecc., Ciò che conta di seguito è solo la velocità e il conteggio dei loop (diverso da zero).
Ecco come la maggior parte delle persone implementa il loop con 10 iterazioni:
int i;
for (i = 0; i < 10; i++)
{
//something here
}
Per il 99% dei casi è tutto ciò di cui si può avere bisogno, ma insieme a PHP, PYTHON, JavaScript c'è tutto il mondo del software critico nel tempo (di solito incorporato, sistema operativo, giochi ecc.) In cui i tick della CPU contano davvero, quindi guarda brevemente il codice assembly di:
int i;
for (i = 0; i < 10; i++)
{
//something here
}
dopo la compilazione (senza ottimizzazione) la versione compilata può apparire così (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:
L'intero ciclo è composto da 8 istruzioni (26 byte). In esso - ci sono in realtà 6 istruzioni (17 byte) con 2 rami. Sì sì, lo so che può essere fatto meglio (è solo un esempio).
Ora considera questo costrutto frequente che troverai spesso scritto dallo sviluppatore incorporato:
i = 10;
do
{
//something here
} while (--i);
Iterate anche 10 volte (sì, lo so, il valore è diverso rispetto a mostrato per il ciclo, ma ci interessa il conteggio dell'iterazione qui). Questo può essere compilato in questo:
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 istruzioni (18 byte) e un solo ramo. In realtà ci sono 4 istruzioni nel loop (11 byte).
La cosa migliore è che alcune CPU (compatibile x86 / x64 incluso) hanno istruzioni che possono decrementare un registro, confrontare successivamente il risultato con zero ed eseguire il ramo se il risultato è diverso da zero. Praticamente TUTTI i PC cpus implementano queste istruzioni. Usarlo il loop è in realtà solo un'istruzione (sì una) da 2 byte:
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
Devo spiegare quale è più veloce?
Ora, anche se una particolare CPU non implementa le istruzioni precedenti, tutto ciò che serve per emularlo è un decremento seguito da un salto condizionale se il risultato dell'istruzione precedente risulta essere zero.
Quindi, indipendentemente da alcuni casi che potresti indicare come un commento, perché mi sbaglio, ecc. Ecc., SOTTOLINEO - SÌ È VANTAGGIOSO SVOLGERE VERSO IL BASSO se sai come, perché e quando.
PS. Sì, lo so che il compilatore saggio (con il livello di ottimizzazione appropriato) riscriverà per loop (con contatore di loop crescente) in do..quanto equivalente per iterazioni di loop costanti ... (o srotolarlo) ...