Поперше:
do-whileПетля не те ж саме , як while-loop або for-loop.
while і for цикли можуть взагалі не запускати тіло циклу.
- A
do-whileЦикл завжди виконується тіло циклу принаймні один раз - він пропускає першу перевірку умови.
Тож це логічна різниця. Тим не менш, не всі суворо цього дотримуються. Це досить часто для whileабоfor циклів використовується навіть тоді, коли гарантується, що він завжди буде цикл хоча б один раз. (Особливо в мовах із циклами foreach .)
Тому, щоб уникнути порівняння яблук та апельсинів, я продовжуватиму, припускаючи, що цикл завжди буде працювати хоча б один раз. Крім того, я не буду згадуватиfor цикли, оскільки це, по суті, whileцикли з трохи синтаксису цукру для лічильника циклів.
Тож я відповім на запитання:
Якщо whileцикл гарантовано повторюється принаймні один раз, чи є збільшення продуктивності від використанняdo-while замість нього циклу.
A do-whileПропускає першу перевірку умови. Отже, є одна гілка менше і одна менша умова для оцінки.
Якщо умова дорого перевіряється, і ви знаєте, що гарантовано повторите принаймні один раз, то do-whileцикл може бути швидшим.
І хоча це в кращому випадку вважається мікрооптимізацією, компілятор не завжди може це зробити: зокрема, коли компілятор не може довести, що цикл завжди ввійде хоча б один раз.
Іншими словами, цикл while:
while (condition){
body
}
Фактично такий самий, як цей:
if (condition){
do{
body
}while (condition);
}
Якщо ви знаєте, що завжди хоч раз будете циклічно повторюватись, цей оператор if буде стороннім.
Так само на рівні збірки, приблизно так компілюються різні цикли, щоб:
цикл do-while:
start:
body
test
conditional jump to start
while-loop:
test
conditional jump to end
start:
body
test
conditional jump to start
end:
Зверніть увагу, що умова продубльовано. Альтернативний підхід:
unconditional jump to end
start:
body
end:
test
conditional jump to start
... який обміняє дублікат коду для додаткового стрибка.
У будь-якому випадку, це все одно гірше звичайного do-whileциклу.
Тим не менш, компілятори можуть робити те, що хочуть. І якщо вони можуть довести, що цикл завжди входить один раз, то він зробив роботу за вас.
Але для конкретного прикладу у питанні все трохи дивно, оскільки він має порожнє тіло циклу. Оскільки немає тіла, немає логічної різниці між whileі do-while.
FWIW, я тестував це у Visual Studio 2012:
З порожнім тілом він насправді генерує той самий код для whileі do-while. Тож ця частина, швидше за все, є залишком старих часів, коли компілятори не були такими чудовими.
Але з непорожнім тілом VS2012 вдається уникнути дублювання коду умови, але все одно генерує додатковий умовний стрибок.
Тому іронічно, що, хоча приклад у питанні підкреслює, чому do-whileцикл може бути швидшим у загальному випадку, сам приклад, здається, не дає жодної користі для сучасного компілятора.
Враховуючи, скільки років був коментар, ми можемо лише здогадуватися, чому це мало значення. Цілком можливо, що укладачі того часу не були здатні визнати, що тіло порожнє. (Або якщо вони це зробили, вони не використовували інформацію.)