2009-02-16 5 views

ответ

46

(обновление) На самом деле - существует один сценарий, в котором конструкция for более эффективна; цикл по массиву. Компилятор/JIT имеет оптимизации для этого сценария до тех пор, пока вы используетеarr.Lengthв состоянии:

for(int i = 0 ; i < arr.Length ; i++) { 
    Console.WriteLine(arr[i]); // skips bounds check 
} 

В этом очень конкретном случае, он пропускает за пределы проверки, так как она уже знает, что он никогда не будет быть вне пределов. Интересно, что если «Подъемник» arr.Length, чтобы попытаться оптимизировать его вручную, чтобы этого не случилось:

int len = arr.Length; 
for(int i = 0 ; i < len ; i++) { 
    Console.WriteLine(arr[i]); // performs bounds check 
} 

Однако с другими контейнерами (List<T> и т.д.), подъемная довольно разумно в качестве ручного микро-оптимизации.

(конец обновления)


Ни; цикл for в любом случае оценивается как цикл while под капотом.

Например 12.3.3.9 из ECMA 334 (определенное назначение) диктует, что цикл:

for (for-initializer ; for-condition ; for-iterator) embedded-statement 

по существу эквивалентно (от Определенной назначении точки зрения (не совсем такими же, как говоря «компилятор должен генерировать этот IL ")) как:

{ 
    for-initializer ; 
    while (for-condition) { 
     embedded-statement ; 
     LLoop: 
     for-iterator ; 
    } 
} 

с продолжать заявления, которые нацелены на в заявлении для переводится на инструкции goto, ориентированные на этикетку LLoop. Если для условия опущено из инструкции for, то оценка определенного задания происходит, как если бы условие было заменено на true в приведенном выше расширении.

Теперь, это не означает, что компилятор должен делать то же самое, но на самом деле это довольно много делает ...

+0

Можете ли вы предоставить источники и цитаты для оптимизации разрывов подъема? – Krythic

+0

@ Krythic просто наткнулся на это: https://codeblog.jonskeet.uk/2009/01/29/for-vs-foreach-on-arrays-and-lists/ сообщение в блоге от Jon Skeet. – NoxMortem

+0

NoxMortem Спасибо – Krythic

2

Ни один. Они эквивалентны. Вы можете думать о том, что цикл «for» является более компактным способом записи цикла while.

12

Я бы сказал, что они такие же, и вы никогда не должны делать такие микро-оптимизации в любом случае.

6

Производительность будет такой же. Однако, если вам не нужен доступ к переменной i за пределами цикла, вы должны использовать цикл for. Это будет более чистым, так как i будет иметь только область внутри блока.

3

Эффективность программы исходит из правильных алгоритмов, хорошего объектного дизайна, интеллектуальной архитектуры программы и т. Д.

Брешьте цикл или два с помощью циклов против циклов, пока петли НИКОГДА не будут делать медленную программу быстро или медленную программу.

Если вы хотите улучшить производительность программы в этом разделе, найдите способ частично развернуть цикл (см. Duff's Device) или улучшить производительность того, что делается внутри цикла.

Смежные вопросы