Po pierwsze:
do-whilePętli nie jest taki sam jak while-loop lub for-loop.
whilea forpętle mogą w ogóle nie uruchamiać treści pętli.
do-whilePętla zawsze przebiega ciało pętli przynajmniej raz - pomija początkową sprawdzić stan.
To jest logiczna różnica. To powiedziawszy, nie wszyscy ściśle przestrzegają tego. Pętle whilelub są dość powszechne, fornawet jeśli jest zagwarantowane, że zawsze będą się zapętlać co najmniej raz. (Szczególnie w językach z pętlami foreach ).
Aby uniknąć porównywania jabłek i pomarańczy, będę zakładał, że pętla zawsze będzie działać co najmniej raz. Ponadto nie będę forponownie wspominał o pętlach, ponieważ zasadniczo sąwhile pętlami z odrobiną cukru składniowego dla licznika pętli.
Odpowiem więc na pytanie:
Jeśli whilepętla jest gwarantowana co najmniej raz, czy użycie do-whilepętli powoduje wzrost wydajności .
A do-whilepomija pierwszą kontrolę stanu. Jest więc jedna gałąź mniej i jeden warunek mniej do oceny.
Jeśli sprawdzenie tego warunku jest drogie i wiesz, że masz gwarancję wykonania pętli co najmniej raz, do-whilepętla może być szybsza.
I chociaż jest to uważane w najlepszym przypadku za mikro-optymalizację, jest to taka, której kompilator nie zawsze może zrobić: w szczególności, gdy kompilator nie jest w stanie udowodnić, że pętla zawsze wejdzie co najmniej raz.
Innymi słowy, pętla while:
while (condition){
body
}
W praktyce to to samo:
if (condition){
do{
body
}while (condition);
}
Jeśli wiesz, że zawsze będziesz co najmniej raz zapętlić, ta instrukcja if jest zbędna.
Podobnie na poziomie zespołu, w ten sposób z grubsza kompilują się różne pętle, aby:
pętla do-while:
start:
body
test
conditional jump to start
pętla while:
test
conditional jump to end
start:
body
test
conditional jump to start
end:
Zwróć uwagę, że warunek został zduplikowany. Alternatywnym podejściem jest:
unconditional jump to end
start:
body
end:
test
conditional jump to start
... który zamienia zduplikowany kod na dodatkowy skok.
Tak czy inaczej, jest to nadal gorsze niż normalna do-whilepętla.
To powiedziawszy, kompilatorzy mogą robić, co chcą. A jeśli uda im się udowodnić, że pętla zawsze pojawia się raz, to wykonała pracę za Ciebie.
Ale sytuacja wygląda nieco dziwnie w przypadku konkretnego przykładu w pytaniu, ponieważ ma on pustą treść pętli. Ponieważ nie ma ciała, nie ma logicznej różnicy między whileido-while .
FWIW, przetestowałem to w Visual Studio 2012:
Z pustą treścią faktycznie generuje ten sam kod dla whilei do-while. Więc ta część jest prawdopodobnie pozostałością po dawnych czasach, kiedy kompilatory nie były tak świetne.
Ale z niepustą treścią VS2012 udaje się uniknąć powielania kodu warunku, ale nadal generuje dodatkowy skok warunkowy.
To ironiczne, że chociaż przykład w pytaniu podkreśla, dlaczego do-whilepętla może być szybsza w ogólnym przypadku, sam przykład nie wydaje się przynosić żadnych korzyści dla nowoczesnego kompilatora.
Biorąc pod uwagę wiek komentarza, możemy tylko zgadywać, dlaczego miałby to znaczenie. Jest bardzo możliwe, że kompilatory w tym czasie nie były w stanie rozpoznać, że ciało było puste. (A jeśli tak, to nie wykorzystali informacji).