LINQ против обычного перечисления

2

Когда у вас есть некоторые методы перечисления в некоторых ваших типах (т.е. пользовательская коллекция), лучше ли использовать синтаксис LINQ или просто старое школьное перечисление (для/foreach)?

Использование .NET 3.5 является данным.

Я прошу об этом для максимальной производительности и удобочитаемости. Приложение также должно быть параллельным.

Какой из них вы предпочитаете?

Теги:
linq
performance

5 ответов

6

Запросы Linq можно легко распараллелить, используя PLinq (встроенный в .net 4)

Я лично считаю, что Linq легче читать, но зависит от вас как разработчика.

foreach (var item in collection)
{
    if (item.Value == SomeOtherValue)
        performSomeProcessing();
}

против

foreach(var item in collection.Where(a => a.Value == SomeOtherValue))
{
    performSomeProcessing();
}

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

3

Если вам абсолютно необходимо выкрутить каждую последнюю производительность, то цикл for/foreach сложно выполнить для эффективности. Однако, если вы собираетесь использовать parallelism и читаемость, методы расширения Enumerable<T> и LINQ выигрывают в моей книге.

  • 1
    Спасибо, с простым LINQ я получу параллельное выполнение? Или ты имеешь ввиду PLINQ?
  • 0
    Вы должны к нам PLINQ для этого.
2

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

2

Функция LINQ to Objects - это смешанная вещь. Поскольку это связано с множеством косвенных вызовов (каждая лямбда одна), она медленнее, иногда (когда лямбда захватывает и использует переменные из ее внешней области) 3-4 раза. И нет, компилятор (ни С#, ни JIT) не будет оптимизировать его - он не может встроить вызовы виртуальных методов и что вызов через делегат эффективно. Поэтому, если вы строго хотите производительность, foreach будет в любом случае немного значительно быстрее.

PLINQ может облегчить разницу, но обратите внимание, что штраф достаточно значителен, чтобы вам понадобилось 4 ядра, чтобы соответствовать ему. С другой стороны, он будет увеличиваться по мере увеличения количества ядер, а простой foreach не будет.

  • 0
    Благодарю. А как насчет Parallel.For?
2

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

Если вы планируете использовать .NET 4.0, параллельные конструкции (в частности, Parallel.For) будут выбивать PLINQ с точки зрения распараллеливания, если вы знаете счет заранее. Разделители в PLINQ выполняют хорошую работу, но сделаны очень общей целью и не могут соответствовать стратегиям разделения, доступным, если счет известен заранее. Это будет иметь тенденцию делать Parallel.For превосходит PLINQ, когда он доступен для использования.

  • 0
    Спасибо, Рид. Я не знал Parallel.For было лучше, когда ты знаешь количество. Как насчет Parallel.Foreach (не знаю, есть ли он).
  • 1
    Вы можете сделать Parallel.Foreach, но у него нет преимуществ. Самым большим преимуществом эффективного распараллеливания является разбиение, особенно если у вас много мелких рабочих элементов. Знание количества позволяет параллельному устройству выполнять более интеллектуальное разбиение заранее, поэтому оно может эффективно группировать рабочие элементы в блоки по задачам, что снижает накладные расходы на синхронизацию.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню