Tout d'abord:
Un do-while
boucle n'est pas la même chose qu'un while
-boucle ou un for
-boucle.
-
while
et for
boucles ne peuvent pas exécuter le corps de la boucle.
- Un
do-while
boucle s'exécute toujours le corps de la boucle au moins une fois - il saute la première condition de vérifier.
Donc, c'est la logique de la différence. Cela dit, tout le monde ne se conforme strictement à cela. Il est assez commun pour while
ou for
boucles pour être utilisé même lorsqu'il est garanti que ce sera toujours de la boucle au moins une fois. (En particulier dans les langues avec foreach boucles.)
Donc pour éviter de comparer des pommes et des oranges, je vais en supposant que la boucle sera toujours exécuté au moins une fois. En outre, je ne vais pas mentionner for
boucles de nouveau, car ils sont essentiellement while
boucles avec un peu de syntaxe de sucre pour un compteur de boucle.
Donc je vais répondre à la question:
Si un while
boucle est garanti à boucle au moins une fois, est-il un gain de performance de l'aide d'un do-while
boucle à la place.
Un do-while
saute la première condition de vérifier. Donc il y a moins de branche et un de moins condition à évaluer.
Si la condition est cher pour le vérifier, et vous savez que vous avez la garantie de la boucle au moins une fois, puis un do-while
boucle pourrait être plus rapide.
Et tout cela est considéré comme un micro-optimisation, au mieux, il est un fait que le compilateur ne peut pas toujours faire: plus Précisément, lorsque le compilateur est pas en mesure de prouver que la boucle sera toujours saisir au moins une fois.
En d'autres termes, un tout-en boucle:
while (condition){
body
}
Est effectivement la même chose que ceci:
if (condition){
do{
body
}while (condition);
}
Si vous savez que vous aurez toujours la boucle au moins une fois, que si l'instruction est superflu.
De même au niveau de l'assemblage, c'est à peu près la façon dont les différentes boucles de la compilation:
-lors de la boucle:
start:
body
test
conditional jump to start
tout en boucle:
test
conditional jump to end
start:
body
test
conditional jump to start
end:
Notez que la condition a été dupliqué. Une autre approche est la suivante:
unconditional jump to end
start:
body
end:
test
conditional jump to start
... qui abandonne le code en double pour un saut supplémentaire.
De toute façon, c'est encore pire que la normale do-while
boucle.
Cela dit, les compilateurs peuvent faire ce qu'ils veulent. Et si elles peuvent prouver que la boucle est toujours entre une fois, puis il a fait le travail pour vous.
Mais les choses sont peu bizarre pour l'exemple en question, car il a un vide corps de boucle. Depuis il n'y a pas de corps, il n'y a pas de logique de la différence entre while
et do-while
.
FWIW, je l'ai testé dans Visual Studio 2012:
Avec le vide d'un corps, il en fait de générer le même code pour while
et do-while
. De sorte qu'une partie est probablement un vestige de l'époque où les compilateurs n'étaient pas aussi grande.
Mais avec un non-vide de corps, VS2012 parvient à éviter la duplication de code condition, mais encore génère un supplément de saut conditionnel.
Il est donc ironique de constater que, bien que l'exemple en question souligne pourquoi un do-while
boucle pourrait être plus rapide dans le cas général, l'exemple lui-même ne semble pas apporter aucun avantage sur un compilateur moderne.
Considérant la façon dont l'ancien commentaire, nous ne pouvons que deviner pourquoi il aurait de l'importance. Il est très possible que les compilateurs à l'époque n'étaient pas capables de reconnaître que le corps était vide. (Ou s'ils le faisaient, ils n'avaient pas l'utilisation de l'information.)