Em primeiro lugar:
Um do-while
loop não é o mesmo que um while
-loop ou um for
-loop.
while
e os for
loops podem nem mesmo executar o corpo do loop.
- Um
do-while
loop sempre executa o corpo do loop pelo menos uma vez - ele ignora a verificação de condição inicial.
Então essa é a diferença lógica. Dito isso, nem todo mundo adere estritamente a isso. É bastante comum o uso de loops for while
ou for
mesmo quando é garantido que ele sempre fará um loop pelo menos uma vez. (Especialmente em idiomas com loops foreach .)
Portanto, para evitar comparar maçãs e laranjas, continuarei presumindo que o loop sempre será executado pelo menos uma vez. Além disso, não mencionarei os for
loops novamente, pois eles são essencialmente while
loops com um pouco de açúcar de sintaxe para um contador de loop.
Portanto, responderei à pergunta:
Se um while
loop tem garantia de loop pelo menos uma vez, há algum ganho de desempenho com o uso de um do-while
loop.
A do-while
ignora a primeira verificação de condição. Portanto, há um ramo a menos e uma condição a menos para avaliar.
Se a verificação da condição for cara e você souber que fará um loop pelo menos uma vez, um do-while
loop pode ser mais rápido.
E embora isso seja considerado, na melhor das hipóteses, uma microotimização, é algo que o compilador nem sempre pode fazer: especificamente quando o compilador não consegue provar que o loop sempre entrará pelo menos uma vez.
Em outras palavras, um loop while:
while (condition){
body
}
É efetivamente o mesmo que este:
if (condition){
do{
body
}while (condition);
}
Se você sabe que sempre fará o loop pelo menos uma vez, essa instrução if é estranha.
Da mesma forma, no nível de montagem, é aproximadamente assim que os diferentes loops são compilados para:
loop do-while:
start:
body
test
conditional jump to start
while-loop:
test
conditional jump to end
start:
body
test
conditional jump to start
end:
Observe que a condição foi duplicada. Uma abordagem alternativa é:
unconditional jump to end
start:
body
end:
test
conditional jump to start
... que troca o código duplicado por um salto adicional.
De qualquer forma, ainda é pior do que um do-while
loop normal .
Dito isso, os compiladores podem fazer o que quiserem. E se eles puderem provar que o loop sempre entra uma vez, isso fez o trabalho para você.
Mas as coisas são um pouco estranhas para o exemplo específico na questão porque ele tem um corpo de loop vazio. Como não há corpo, não há diferença lógica entre while
e do-while
.
FWIW, testei isso no Visual Studio 2012:
Com o corpo vazio, ele realmente gera o mesmo código para while
e do-while
. Essa parte provavelmente é um resquício dos velhos tempos, quando os compiladores não eram tão bons.
Mas com um corpo não vazio, VS2012 consegue evitar a duplicação do código de condição, mas ainda gera um salto condicional extra.
Portanto, é irônico que, embora o exemplo da pergunta destaque por que um do-while
loop poderia ser mais rápido no caso geral, o exemplo em si não parece oferecer nenhum benefício em um compilador moderno.
Considerando a idade do comentário, só podemos imaginar por que ele seria importante. É bem possível que os compiladores da época não fossem capazes de reconhecer que o corpo estava vazio. (Ou, se usaram, não usaram as informações.)