Prima di tutto:
Un do-while
ciclo non è la stessa cosa di un while
ciclo o di un for
ciclo.
while
e i for
cicli potrebbero non eseguire affatto il corpo del ciclo.
- Un
do-while
ciclo esegue sempre il corpo del ciclo almeno una volta: salta il controllo delle condizioni iniziali.
Quindi questa è la differenza logica. Detto questo, non tutti aderiscono strettamente a questo. È abbastanza comune utilizzare i loop while
o for
anche quando è garantito che verrà sempre eseguito almeno una volta. (Soprattutto nelle lingue con cicli foreach .)
Quindi, per evitare di confrontare mele e arance, procederò supponendo che il ciclo verrà sempre eseguito almeno una volta. Inoltre, non menzionerò più i for
loop poiché sono essenzialmente while
loop con un po 'di zucchero di sintassi per un contatore di loop.
Quindi risponderò alla domanda:
Se while
è garantito che un loop venga eseguito almeno una volta, c'è qualche miglioramento in termini di prestazioni dall'utilizzo di un do-while
loop.
A do-while
salta il primo controllo delle condizioni. Quindi c'è un ramo in meno e una condizione in meno da valutare.
Se la condizione è costosa da controllare e sai di avere la certezza di eseguire il loop almeno una volta, un do-while
loop potrebbe essere più veloce.
E anche se nel migliore dei casi questa è considerata una microottimizzazione, è quella che il compilatore non può sempre fare: in particolare quando il compilatore non è in grado di dimostrare che il ciclo entrerà sempre almeno una volta.
In altre parole, un ciclo while:
while (condition){
body
}
È effettivamente lo stesso di questo:
if (condition){
do{
body
}while (condition);
}
Se sai che ripeterai sempre almeno una volta, quell'istruzione if è estranea.
Allo stesso modo a livello di assembly, questo è più o meno il modo in cui i diversi loop si compilano per:
ciclo do-while:
start:
body
test
conditional jump to start
while loop:
test
conditional jump to end
start:
body
test
conditional jump to start
end:
Notare che la condizione è stata duplicata. Un approccio alternativo è:
unconditional jump to end
start:
body
end:
test
conditional jump to start
... che scambia il codice duplicato per un ulteriore salto.
Ad ogni modo, è ancora peggio di un normale do-while
loop.
Detto questo, i compilatori possono fare quello che vogliono. E se possono provare che il ciclo entra sempre una volta, allora ha fatto il lavoro per te.
Ma le cose sono un po 'strane per l'esempio particolare nella domanda perché ha un corpo del ciclo vuoto. Poiché non esiste un corpo, non esiste alcuna differenza logica tra while
e do-while
.
FWIW, l'ho testato in Visual Studio 2012:
Con il corpo vuoto, genera effettivamente lo stesso codice per while
e do-while
. Quindi quella parte è probabilmente un residuo dei vecchi tempi in cui i compilatori non erano così grandi.
Ma con un corpo non vuoto, VS2012 riesce a evitare la duplicazione del codice della condizione, ma genera comunque un salto condizionale aggiuntivo.
Quindi è ironico che mentre l'esempio nella domanda evidenzia perché un do-while
ciclo potrebbe essere più veloce nel caso generale, l'esempio stesso non sembra dare alcun vantaggio su un compilatore moderno.
Considerando l'età del commento, possiamo solo immaginare perché sarebbe importante. È molto probabile che i compilatori all'epoca non fossero in grado di riconoscere che il corpo era vuoto. (O se lo hanno fatto, non hanno usato le informazioni.)