В .NET какой цикл выполняется быстрее, «для» или «foreach»?

В C # / VB.NET / .NET какой цикл работает быстрее forили foreach?

С тех пор, как я прочитал, что forцикл работает быстрее, чем foreachцикл давным-давно, я предположил, что это верно для всех коллекций, универсальных коллекций, всех массивов и т. Д.

Я просмотрел Google и нашел несколько статей, но большинство из них неубедительны (читай комментарии к статьям) и открыты.

То, что было бы идеально, - это перечислить каждый сценарий и найти лучшее решение для него.

Например (просто пример того, как это должно быть):

  1. для перебора массива из 1000+ строк - forлучше, чемforeach
  2. для перебора IList(не универсальных) строк - foreachлучше, чемfor

Несколько ссылок, найденных в Интернете для того же:

  1. Оригинальная старая статья Эммануэля Шанцера
  2. CodeProject FOREACH Vs. ЗА
  3. Блог - к foreachили нет foreach, вот в чем вопрос
  4. Форум ASP.NET - NET 1.1 C # forпротивforeach

[Редактировать]

Помимо аспекта читабельности, меня действительно интересуют факты и цифры. Есть приложения, в которых важна последняя миля оптимизации производительности.

13.12.2008 19:45:42
Разница все еще существует. В частности, массивы должны быть такими же быстрыми в foreach, но для всего остального простые циклы быстрее. Конечно, в большинстве случаев это не будет иметь значения, и, конечно, умный JIT-компилятор может теоретически устранить разницу.
jalf 13.12.2008 22:53:27
Без контекста я не могу точно знать, что вы делаете, но что происходит, когда вы сталкиваетесь с частично заполненным массивом?
Chris Cudmore 22.12.2009 15:18:15
Кстати, 2 миллиона показов в месяц - ничего страшного. Это в среднем меньше, чем хит в секунду.
Mehrdad Afshari 22.12.2009 15:46:32
Важное примечание : вчера этот вопрос был объединен с совершенно не связанным с этим вопросом о том, чтобы его заставляли использовать foreachвместо forC #. Если вы видите здесь ответы, которые вообще не имеют смысла, вот почему. Виноват модератор, а не несчастные ответы.
T.E.D. 27.05.2010 13:35:39
@TED ​​О, мне было интересно, откуда все комментарии "твой босс - идиот", откуда они, спасибо
Gaspa79 21.07.2016 17:27:00
30 ОТВЕТОВ
РЕШЕНИЕ

Об этом в прошлом месяце написал Патрик Смаккья со следующими выводами:

  • Циклы for в List чуть более чем в 2 раза дешевле, чем циклы foreach в List.
  • Зацикливание в массиве примерно в 2 раза дешевле, чем зацикливание в List.
  • Как следствие, зацикливание на массиве с использованием for в 5 раз дешевле, чем зацикливание на List с использованием foreach (что, я считаю, является тем, что мы все делаем).
346
13.12.2008 20:19:54
Однако никогда не забывайте: «Преждевременная оптимизация - корень всего зла».
Oorang 29.05.2009 04:53:45
@Hardwareguy: Если вы знаете, что for почти незаметно быстрее, почему бы вам вообще не начать его использовать? Это не займет дополнительное время.
DevinB 3.09.2009 13:06:36
@devinb, использовать «for» сложнее, чем «foreach», так как он добавляет код, другую переменную, условие, которое нужно проверить, и т. д. Сколько раз вы видели ошибку «один за другим» в цикле «foreach» ?
tster 3.12.2009 15:45:15
@ Hardwareguy, дай мне посмотреть, правильно ли я понял. Для циклического перемещения по списку требуется в 5 раз больше времени, foreachчем для обхода массива for, и вы называете это незначительным? Такая разница в производительности может иметь значение для вашего приложения, а может и нет, но я бы просто не отмахнулся от нее.
Robert Harvey 23.12.2009 00:04:07
Прочитав сообщение в блоге, похоже, что тесты были запущены в Debug, а не в Release, так что это может иметь значение. Кроме того, разница специально для заголовка цикла. Это никак не влияет на время выполнения тела цикла, которое в большинстве случаев намного дольше, чем время, необходимое для перехода к следующему элементу списка. Полезно знать, когда вы определили, что существует определенная проблема, и вы конкретно измерили разницу в своем приложении, и есть заметное улучшение, но определенно нет общего совета по удалению всех foreachs.
Davy8 27.05.2010 13:26:49

Я предполагаю, что это, вероятно, не будет значимым в 99% случаев, так почему бы вам выбрать более быстрый, а не наиболее подходящий (как это проще всего понять / сохранить)?

36
13.12.2008 19:51:41
@klew, если вы на самом деле профилируете свой код, вам не придется угадывать, какие 20% должны быть максимально быстрыми. Вы, вероятно, также узнаете, что фактическое число циклов, которые должны быть быстрыми, намного меньше. Кроме того, вы действительно говорите, что зацикливание - это то, где вы проводите свое время, а не то, что вы фактически делаете в этом цикле?
tster 3.12.2009 15:47:08

Это всегда будет близко. Для массива иногда for немного быстрее, но foreachон более выразителен и предлагает LINQ и т. Д. В общем, придерживайтесь foreach.

Кроме того, foreachможет быть оптимизирован в некоторых сценариях. Например, связанный список может быть ужасным для индексатора, но он может быть быстрым foreach. На самом деле, стандарт LinkedList<T>даже не предлагает индексатор по этой причине.

49
13.06.2012 17:46:25
Так ты говоришь, LinkedList<T>что стройнее, чем List<T>? И если я всегда буду использовать foreach(вместо for), мне лучше использовать LinkedList<T>?
JohnB 26.05.2010 20:00:19
@JohnB - не стройнее; просто другой. Например, каждый узел в связанном списке имеет дополнительные ссылки, которые не нужны для плоского массива (который также лежит в основе List<T>). Больше того, что дешевле вставить / удалить .
Marc Gravell♦ 26.05.2010 21:37:52

Я проверял это некоторое время назад, в результате чего forцикл намного быстрее, чем foreachцикл. Причина проста, foreachцикл должен сначала создать экземпляр IEnumeratorдля коллекции.

1
13.06.2012 17:47:49
Не с массивом это не так. Скомпилируйте его и посмотрите на IL :) (Это также зависит от коллекции. IIRC, List <T> использует тип значения для перечислителя.)
Jon Skeet 13.12.2008 20:34:15
Почему одно распределение будет дорогим? В управляемом .NET распределения практически бесплатны, не так ли, поскольку все, что делается, заключается в том, что указатель увеличивается в управляемой куче, в большинстве случаев практически отсутствует фрагментация.
ApplePieIsGood 13.12.2008 20:48:50
не только одно выделение, но и все накладные расходы на вызовы методов MoveNext () и get_Current () для каждой итерации.
Lucas 19.05.2009 19:47:30

for имеет более простую логику для реализации, поэтому она быстрее, чем foreach.

3
13.12.2008 19:59:32

Различия в скорости в for- и foreach-loop крошечные, когда вы просматриваете общие структуры, такие как массивы, списки и т. Д., И выполнение LINQзапроса к коллекции почти всегда немного медленнее, хотя писать приятнее! Как говорили другие авторы, стремитесь к выразительности, а не к миллисекунде дополнительной производительности.

До сих пор не было сказано, что когда foreachцикл компилируется, он оптимизируется компилятором на основе коллекции, по которой он перебирает. Это означает, что когда вы не уверены, какой цикл использовать, вы должны использовать foreachцикл - он сгенерирует лучший цикл для вас, когда будет скомпилирован. Это также более читабельно.

Другое ключевое преимущество foreachцикла состоит в том, что если ваша реализация коллекции изменится (например, с int arrayна a List<int>), то ваш foreachцикл не потребует никаких изменений кода:

foreach (int i in myCollection)

Выше одно и то же, независимо от типа вашей коллекции, тогда как в вашем forцикле следующее не будет построено, если вы изменили myCollectionс a arrayна a List:

for (int i = 0; i < myCollection.Length, i++)
7
13.12.2008 22:44:27

Вероятно, это зависит от типа коллекции, которую вы перечисляете, и от реализации ее индексатора. В целом, использование foreach, вероятно, будет лучшим подходом.

Кроме того, он будет работать с любыми IEnumerable- не только с индексаторами.

7
13.06.2012 17:50:06

Вряд ли между ними будет огромная разница в производительности. Как всегда, когда сталкиваешься с "что быстрее?" Вопрос, вы всегда должны думать: «Я могу измерить это».

Напишите два цикла, которые делают одно и то же в теле цикла, выполните и рассчитайте их оба, и посмотрите, какова разница в скорости. Делайте это с почти пустым телом и телом цикла, похожим на то, что вы на самом деле будете делать. Попробуйте также использовать тип используемой коллекции, потому что разные типы коллекций могут иметь разные характеристики производительности.

32
23.01.2009 07:36:03

Сначала встречный иск к ответу Дмитрия (теперь удален) . Для массивов компилятор C # выдает в основном тот же код, foreachчто и для эквивалентного forцикла. Это объясняет, почему для этого теста результаты в основном такие же:

using System;
using System.Diagnostics;
using System.Linq;

class Test
{
    const int Size = 1000000;
    const int Iterations = 10000;

    static void Main()
    {
        double[] data = new double[Size];
        Random rng = new Random();
        for (int i=0; i < data.Length; i++)
        {
            data[i] = rng.NextDouble();
        }

        double correctSum = data.Sum();

        Stopwatch sw = Stopwatch.StartNew();
        for (int i=0; i < Iterations; i++)
        {
            double sum = 0;
            for (int j=0; j < data.Length; j++)
            {
                sum += data[j];
            }
            if (Math.Abs(sum-correctSum) > 0.1)
            {
                Console.WriteLine("Summation failed");
                return;
            }
        }
        sw.Stop();
        Console.WriteLine("For loop: {0}", sw.ElapsedMilliseconds);

        sw = Stopwatch.StartNew();
        for (int i=0; i < Iterations; i++)
        {
            double sum = 0;
            foreach (double d in data)
            {
                sum += d;
            }
            if (Math.Abs(sum-correctSum) > 0.1)
            {
                Console.WriteLine("Summation failed");
                return;
            }
        }
        sw.Stop();
        Console.WriteLine("Foreach loop: {0}", sw.ElapsedMilliseconds);
    }
}

Результаты:

For loop: 16638
Foreach loop: 16529

Далее, проверка того, что Грег говорит о важности типа коллекции - измените массив на a List<double>в приведенном выше, и вы получите радикально разные результаты. Это не только значительно медленнее в целом, но foreach становится значительно медленнее, чем доступ по индексу. Сказав это, я все равно почти всегда предпочитаю foreach циклу for, где он упрощает код - потому что читаемость почти всегда важна, а микрооптимизация редко.

163
11.03.2020 18:27:17
«Измените массив на List <double> в приведенном выше, и вы получите совершенно другие результаты» Очень интересно, я не думал об этом
johnc 23.01.2009 10:12:41
Учитывая странные различия в результатах между моими тестами и тестами других людей, я думаю, что это заслужит пост в блоге ...
Jon Skeet 23.01.2009 10:19:35
Что вы почти всегда предпочитаете между массивами и List<T>? В этом случае удобочитаемость превосходит микрооптимизацию?
JohnB 27.05.2010 16:18:15
@JohnB: Да, я почти всегда предпочитаю List<T>массивы. Исключения char[]и byte[]которые чаще рассматриваются как «куски» данные , а не обычные коллекции.
Jon Skeet 27.05.2010 16:38:56
Удивительно, но я получаю еще более агрессивную разницу на моей машине, почти на 10% в пользу foreach на простых массивах. Я дико догадываюсь, что все это происходит из-за дрожания, не нужно беспокоиться о дополнительных переменных, связанных проверках и т. Д. Было бы очень интересно, если бы у кого-то было глубокое объяснение этого.
Tamir Daniely 30.06.2019 21:00:39

Я бы предложил прочитать это для конкретного ответа. Вывод статьи заключается в том, что использование цикла for обычно лучше и быстрее, чем цикл foreach.

0
23.01.2009 08:45:57
Этот вывод был написан в 2004 году. Все пошло дальше. Смотрите мой тест.
Jon Skeet 23.01.2009 09:27:33

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

Если итератор уже настроен, как, например, с одним из классов коллекции, тогда foreach является хорошим простым вариантом. И если вы перебираете целочисленный диапазон, то, вероятно, он чище.

3
23.01.2009 09:02:19

Джеффри Рихтер рассказал о разнице в производительности между for и foreach в недавнем подкасте: http://pixel8.infragistics.com/shows/everything.aspx#Episode:9317

3
23.01.2009 10:16:38

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

Я предполагаю, что ответ зависит от того, имеет ли доступ к коллекции, к которой вы пытаетесь получить, более быструю реализацию доступа к индексаторам или более быструю реализацию доступа IEnumerator. Поскольку IEnumerator часто использует индексатор и просто хранит копию текущей позиции индекса, я ожидаю, что доступ к перечислителю будет, по крайней мере, таким же медленным или медленным, как прямой доступ к индексу, но ненамного.

Конечно, этот ответ не учитывает оптимизацию, которую может реализовать компилятор.

2
23.01.2009 10:29:29
Компилятор C # делает очень мало оптимизации, он действительно оставляет это на усмотрение JITter.
ljs 25.01.2009 00:24:16
Ну, JITter - это компилятор ... Верно?
JohannesH 30.01.2009 05:41:08

Имейте в виду, что цикл for и цикл foreach не всегда эквивалентны. Перечислители списка будут генерировать исключение, если список изменится, но вы не всегда получите это предупреждение с обычным циклом for. Вы можете даже получить другое исключение, если список меняется не вовремя.

2
17.02.2009 16:59:48
Если список меняется из-за вас, вы не можете полагаться на счетчик, поддерживающий цикл foreach, чтобы сказать вам это. Он не будет проверять снова после того, как вернет вам значение, что приведет к гонке.
hoodaticus 30.03.2017 17:42:54

Джеффри Рихтер на TechEd 2005:

«Я пришел к выводу, что на протяжении многих лет компилятор C # для меня лжец». .. "Это ложь о многих вещах." .. "Например, когда вы делаете цикл foreach ..." .. "... это одна маленькая строчка кода, которую вы пишете, но то, что выкладывает компилятор C # для того, чтобы сделать это феноменальным. там блок try / finally, внутри блока finally он преобразует вашу переменную в интерфейс IDisposable, и если приведение завершается успешно, он вызывает для него метод Dispose, внутри цикла он вызывает свойство Current, а метод MoveNext несколько раз внутри цикла, объекты создаются под крышками. Многие люди используют foreach, потому что это очень легко кодировать, очень легко делать ... ".." foreach не очень хорош с точки зрения производительности,

Веб-трансляция по требованию: http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032292286&EventCategory=3&culture=en-US&CountryCode=US

18
3.12.2009 15:38:08

foreachциклы демонстрируют более конкретное намерение, чем forциклы .

Использование foreachцикла демонстрирует всем, кто использует ваш код, что вы планируете что-то сделать для каждого члена коллекции независимо от его места в коллекции. Это также показывает, что вы не изменяете исходную коллекцию (и выдает исключение, если вы пытаетесь это сделать).

Другое преимущество foreachзаключается в том, что он работает в любом месте IEnumerable, где forимеет смысл только то IList, где каждый элемент фактически имеет индекс.

Однако, если вам нужно использовать индекс элемента, то, конечно, вам должно быть разрешено использовать forцикл. Но если вам не нужно использовать индекс, его просто загромождает ваш код.

Насколько я знаю, никаких существенных последствий для производительности нет. На каком-то этапе в будущем будет проще адаптировать код foreachдля работы на нескольких ядрах, но сейчас не о чем беспокоиться.

162
4.04.2011 12:56:54
ctford: нет, это не так. Компилятор, конечно, не может переупорядочивать элементы в foreach. foreachнисколько не связано с функциональным программированием. Это абсолютно обязательная парадигма программирования. Вы неправильно приписываете вещи, происходящие в TPL и PLINQ foreach.
Mehrdad Afshari 22.12.2009 15:53:33
@BlueTrin: Это, безусловно, гарантирует порядок (раздел 8.8.4 спецификации C # формально определяет foreachкак эквивалент whileцикла). Я думаю, я знаю, что @ctford имеет в виду. Задача параллельной библиотеки позволяет базовой коллекции предоставлять элементы в произвольном порядке (путем вызова .AsParallelперечислимого). foreachздесь ничего не делается, и тело цикла выполняется в одном потоке . Единственное, что распараллелено, - это генерация последовательности.
Mehrdad Afshari 22.12.2009 16:11:37
Enumerable.Select имеет перегрузку, позволяющую получить индекс элемента, поэтому даже необходимость в индексе не требует использования for. См. Msdn.microsoft.com/en-us/library/bb534869.aspx
TrueWill 22.12.2009 18:16:51
ForEach удобен для удобства чтения и сохранения набора текста. Затраты имеют значение, хотя; изменение 2 или 3 циклов for в пользовательском интерфейсе дизайнера документов, которое я сделал, с (для каждого объекта в списке) на (для i = 0 до list.count-1) уменьшило время отклика с 2-3 секунд на редактирование до примерно. 5 секунд на редактирование небольшого документа, просто повторяя несколько сотен объектов. Теперь даже для огромных документов нет увеличения времени, чтобы зациклить все. Я понятия не имею, как это произошло. Что я знаю, так это то, что альтернативой была сложная схема, состоящая в том, чтобы зацикливать только подмножество объектов. Я возьму 5-минутную смену в любой день! - не микрооптимизация.
FastAl 31.03.2011 13:37:10
@FastAl Разница между foreachи forпроизводительностью для обычных списков составляет доли секунды для итерации по миллионам элементов, поэтому ваша проблема, конечно, не была напрямую связана с производительностью foreach, по крайней мере, для нескольких сотен объектов. Походит на сломанную реализацию перечислителя в любом списке, который вы использовали.
Mike Marynowski 26.11.2017 01:38:56

В случаях, когда вы работаете с коллекцией объектов, foreachэто лучше, но если вы увеличиваете число, forцикл лучше.

Обратите внимание, что в последнем случае вы можете сделать что-то вроде:

foreach (int i in Enumerable.Range(1, 10))...

Но он, конечно, не работает лучше, на самом деле он хуже по сравнению с for.

11
5.06.2018 08:14:35
«Лучше» является спорным: Это медленнее и dnspy отладчик не сломается в C # Еогеаспа (хотя VS2017 отладчика). Иногда удобочитаемее, но если вы поддерживаете языки без него, это может раздражать.
Zeek2 26.07.2018 09:21:12

Два будут работать практически одинаково. Напишите некоторый код, чтобы использовать оба, затем покажите ему IL. Он должен показывать сопоставимые вычисления, что означает отсутствие различий в производительности.

4
22.12.2009 15:08:28
Компилятор распознает циклы foreach, используемые в массивах / ILists и т. Д., И изменяет их на циклы for.
Callum Rogers 22.12.2009 15:13:53
Покажите ему строки неразборчивых доказательств того, что все в порядке, и попросите доказательств того, что это не так.
cjk 22.12.2009 15:45:09

Каждый раз, когда возникают споры по поводу производительности, вам просто нужно написать небольшой тест, чтобы вы могли использовать количественные результаты для поддержки вашего случая.

Используйте класс StopWatch и повторите что-то несколько миллионов раз для точности. (Это может быть трудно без цикла for):

using System.Diagnostics;
//...
Stopwatch sw = new Stopwatch()
sw.Start()
for(int i = 0; i < 1000000;i ++)
{
    //do whatever it is you need to time
}
sw.Stop();
//print out sw.ElapsedMilliseconds

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

53
22.02.2012 21:21:57
Но вы не можете сравнить производительность для и foreach. Они должны быть использованы в разных обстоятельствах.
Michael Krelin - hacker 22.12.2009 15:11:57
Я согласен с вами, Майкл, вы не должны выбирать, какой из них использовать в зависимости от производительности - вы должны выбрать тот, который имеет больше смысла! Но если ваш босс говорит: «Не используйте, потому что он медленнее, чем foreach», тогда это единственный способ убедить его в том, что разница незначительна
Rob Fonseca-Ensor 22.12.2009 15:19:43
«(Это может быть трудно без цикла for)» Или вы можете использовать цикл while.
jonescb 22.12.2009 18:42:07

Это смешно. Нет никаких веских причин, чтобы запретить цикл, производительность или другие.

См . Блог Джона Скита для оценки производительности и других аргументов.

12
28.10.2015 09:52:06
Обновленная ссылка: codeblog.jonskeet.uk/2009/01/29/…
Matt 27.10.2015 16:11:53
Быстрая конструкция цикла зависит от того, что вам нужно перебрать. Другой блог, который сравнивает несколько итераций с различными типами объектов , такими как DataRows и пользовательские объекты. Он также включает производительность конструкции цикла While, а не только конструкции цикла for и foreach.
Free Coder 24 20.05.2016 07:10:04

По крайней мере, я не видел, чтобы кто-нибудь из моих коллег или высших должностных лиц говорил это, это просто смешно, учитывая тот факт, что между forи нет существенной разницы в скорости foreach. То же самое относится, если он просит использовать его во всех случаях!

0
13.06.2012 17:59:35

Кажется немного странным полностью запретить использование чего-то вроде цикла for.

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

Лично я бы сказал, что я нахожу foreach немного более читаемым для циклов, но вы должны использовать лучшее для текущей работы и не нужно писать слишком длинный код для включения цикла foreach, если цикл for более уместен.

3
29.09.2010 14:41:09
Необходимая цитата из статьи, на которую вы ссылаетесь: «... если вы планируете писать высокопроизводительный код, который не предназначен для коллекций, используйте для цикла. Даже для коллекций foreach может показаться удобным при использовании, но это не так эффективно».
NickFitz 22.12.2009 16:54:55

В большинстве случаев нет никакой разницы.

Как правило, вы всегда должны использовать foreach, когда у вас нет явного числового индекса, и вы всегда должны использовать его, когда у вас нет итеративной коллекции (например, итерации по двумерной сетке массива в верхнем треугольнике) , В некоторых случаях у вас есть выбор.

Можно утверждать, что циклы for могут быть немного сложнее поддерживать, если в коде начинают появляться магические числа. Вы должны быть правы, если будете раздражены тем, что не можете использовать цикл for и должны собирать коллекцию или использовать лямбду для создания подколлекции вместо этого только потому, что циклы for были запрещены.

3
22.12.2009 15:28:42

Есть очень веские причины, чтобы предпочесть foreach петли над forпетлями. Если вы можете использовать foreachпетлю, ваш босс прав, что вы должны.

Однако не каждая итерация просто просматривает список по порядку. Если он запрещает , да, это неправильно.

На вашем месте я бы превратил все ваши естественные циклы в рекурсию . Это научит его, и это также хорошее умственное упражнение для вас.

32
22.06.2012 16:17:13
Как рекурсия сравнивается с forциклами и foreachциклами по производительности?
JohnB 27.05.2010 05:18:41
Это зависит. Если вы используете хвостовую рекурсию и ваш компилятор достаточно умен, чтобы заметить, он может быть идентичным. OTOH: Если этого не происходит, и вы делаете что-то глупое, например, передаете много несекретных (неизменяемых) данных в качестве параметров или объявляете большие структуры в стеке как локальные, это может быть очень медленным (или даже нехваткой ОЗУ).
T.E.D. 27.05.2010 12:55:04
Ааа. Я понимаю, почему вы спросили это сейчас. Этот ответ пошел на совершенно другой вопрос. По какой-то странной причине Джонатан Сэмпсон вчера объединил их. Он действительно не должен был этого делать. Объединенные ответы не будут иметь здесь никакого смысла.
T.E.D. 27.05.2010 13:02:37

Будь forбыстрее, чем foreachна самом деле, кроме сути. Я серьезно сомневаюсь, что выбор одного из других окажет значительное влияние на вашу производительность.

Лучший способ оптимизировать ваше приложение - это профилирование реального кода. Это позволит точно определить методы, на которые приходится больше всего работы / времени. Оптимизируйте те сначала. Если производительность по-прежнему не приемлема, повторите процедуру.

Как правило, я бы рекомендовал держаться подальше от микрооптимизаций, поскольку они редко приносят какие-либо существенные выгоды. Единственное исключение - при оптимизации идентифицированных «горячих путей» (т. Е. Если ваше профилирование идентифицирует несколько широко используемых методов, возможно, имеет смысл оптимизировать их экстенсивно).

5
22.12.2009 16:51:17
Если бы в проектах, над которыми я работаю, единственным видом оптимизации было микрооптимизация, я был бы счастливым туристом. К сожалению, это никогда не так.
Yannick Motton 22.12.2009 15:43:58
forнезначительно быстрее, чем foreach. Я серьезно возражаю против этого заявления. Это полностью зависит от основной коллекции. Если класс связанного списка предоставляет индексатору с целочисленным параметром, я ожидал бы, что использование forцикла для него будет O (n ^ 2), в то время foreachкак ожидается, что O (n).
Mehrdad Afshari 22.12.2009 16:17:39
@Merhdad: На самом деле это хороший момент. Я просто думал о обычном случае индексации списка (то есть массива). Я перефразирую это, чтобы отразить это. Спасибо.
Brian Rasmussen 22.12.2009 16:50:47
@ Mehrdad Afshari: индексирование коллекции по целому числу может быть намного медленнее, чем перечисление по ней. Но вы на самом деле сравниваете использование for и поиск индексатора с использованием foreachотдельно. Я думаю, что ответ @Brian Rasmussen правильный, что, помимо любого использования с коллекцией, forвсегда будет немного быстрее, чем foreach. Тем не менее, forпоиск коллекции всегда будет медленнее, чем foreachсам по себе.
Daniel Pryden 22.12.2009 16:52:33
@Daniel: Либо у вас есть простой массив, для которого оба будут генерировать идентичный код, либо при использовании forоператора используется индексатор . Обычный forцикл с целочисленной переменной управления не сравним с foreach, так что нет. Я понимаю, что означает @Brian, и, как вы говорите, это правильно, но ответ может вводить в заблуждение. Re: ваш последний пункт: нет, на самом деле, forпо- List<T>прежнему быстрее, чем foreach.
Mehrdad Afshari 22.12.2009 16:59:33

Вы можете реально прикрутить его голову и вместо этого пойти на закрытие IQueryable .foreach:

myList.ForEach(c => Console.WriteLine(c.ToString());
3
11.03.2020 18:28:03
Я бы заменил вашу строку кода на myList.ForEach(Console.WriteLine).
Mehrdad Afshari 22.12.2009 16:16:13

«Есть ли какие-либо аргументы, которые я мог бы использовать, чтобы убедить его, что цикл for допустим?»

Нет, если ваш начальник на микроуровне говорит о том, какие конструкции языка программирования использовать, вам нечего сказать. Сожалею.

7
22.12.2009 15:50:52

Я думаю, что в большинстве случаев он незначительно быстрее, чем foreach, но это действительно упускает смысл. Одна вещь, о которой я не упомянул, заключается в том, что в сценарии, о котором вы говорите (то есть в веб-приложении большого объема), разница в производительности между for и foreach не будет иметь никакого отношения к производительности сайта. Вы будете ограничены временем запроса / ответа и временем БД, а не v. Foreach.

Тем не менее, я не понимаю ваше отвращение к foreach. На мой взгляд, foreach обычно более понятен в ситуации, когда можно использовать любой из них. Я обычно резервирую для ситуаций, когда мне нужно пройти коллекцию некрасивым, нестандартным способом.

0
22.12.2009 15:58:18
Мне нравится иметь возможность контролировать вещи по индексу. В цикле foreach вы должны вместо этого установить переменную и увеличить ее внутри foreach, если вам нужен счетчик. Я думаю, если вам не нужен индекс, то я в порядке с foreach.
PositiveGuy 23.12.2009 05:02:01
Это верно Я просто нахожу в большинстве сценариев, что я хочу "сделать что-то" для каждого элемента. Если вам нужно знать, где вы находитесь в коллекции, это, безусловно, путь.
Sean Devlin 23.12.2009 05:29:00

Именно то, что вы делаете внутри цикла, влияет на производительность, а не на фактическую конструкцию цикла (при условии, что ваш случай нетривиален).

5
22.12.2009 16:13:47

Каждая языковая конструкция имеет подходящее время и место для использования. Есть причина, по которой язык C # имеет четыре отдельных итерационных оператора - каждый из них предназначен для определенной цели и имеет соответствующее применение.

Я рекомендую сесть с вашим боссом и попытаться рационально объяснить, почему у forцикла есть цель. Есть моменты, когда forитерационный блок более четко описывает алгоритм, чем foreachитерация. Когда это правда, уместно использовать их.

Я также хотел бы отметить вашего босса - производительность не является и не должна быть проблемой в практическом плане - это скорее вопрос выражения алгоритма в сжатой, содержательной и понятной форме. Подобные микрооптимизации полностью упускают смысл оптимизации производительности, поскольку любое реальное преимущество в производительности будет достигнуто за счет алгоритмического реорганизации и рефакторинга, а не реструктуризации цикла.

Если после рационального обсуждения все еще сохраняется авторитарный взгляд, то вам решать, как действовать дальше. Лично я не был бы счастлив работать в среде, где рациональное мышление не поощрялось, и подумал бы о переходе на другую должность под другим работодателем. Тем не менее, я настоятельно рекомендую обсудить это до того, как расстроиться - может быть просто недоразумение.

6
22.12.2009 18:11:14