C # Производительность LINQ против итераторского блока foreach - PullRequest
9 голосов
/ 16 марта 2011

1) Они генерируют один и тот же байт-код?

2) Если нет, есть ли преимущество в использовании одного над другим в определенных обстоятельствах?

// LINQ select statement
return from item in collection
    select item.Property;

// foreach in an iterator block
foreach (item in collection)
    yield return item.Property;

Ответы [ 2 ]

8 голосов
/ 16 марта 2011
  1. Они не генерируют один и тот же код, но сводятся к одному и тому же, вы получаете объект, реализующий IEnumerable<typeof(Property)>.Разница в том, что linq предоставляет итератор из своей библиотеки (в этом случае, скорее всего, с использованием WhereSelectArrayIterator или WhereSelectListIterator), тогда как во втором примере вы сами генерируете блок итератора, который разбирает коллекцию.Блочный метод итератора всегда с помощью магии компилятора компилируется как отдельный класс, реализующий IEnumerable<typeof(yield)>, который вы не видите, но неявно создаете, когда вызываете блочный метод итератора.

  2. С точки зрения производительности, # 1 должен быть немного (но немного) быстрее для индексируемых коллекций, потому что, когда вы перебираете получившийся IEnumerable, вы переходите непосредственно из своего foreach в поиск коллекции воптимизированный linq итератор.В примере №2 вы переходите от foreach к foreach вашего блока итератора и оттуда к извлечению коллекций, и ваша производительность в основном зависит от того, насколько умным компилятор оптимизирует логику выхода.В любом случае я мог бы представить, что для любого сложного механизма сбора стоимость поиска маргинализирует эту разницу.

ИМХО, я бы всегда пошел с # 1, если ничто иное не спасет меня отнаписать отдельный метод только для итерации.

3 голосов
/ 16 марта 2011
  1. Нет, они не генерируют один и тот же байт-код.Первый возвращает уже существующий класс в фреймворке.Второй возвращает созданный компилятором конечный автомат, который возвращает элементы из коллекции.Этот конечный автомат очень похож на класс, который уже существует в фреймворке.

  2. Я сомневаюсь, что между ними существует большая разница в производительности.В итоге оба делают очень похожие вещи.

...