Означает ли порядок функций LINQ?

В принципе, по мере того, как возникает вопрос … имеет ли смысл функционирование LINQ с точки зрения производительности ? Очевидно, что результаты должны быть одинаковыми …

Пример:

myCollection.OrderBy(item => item.CreatedDate).Where(item => item.Code > 3); myCollection.Where(item => item.Code > 3).OrderBy(item => item.CreatedDate); 

Оба возвращают мне те же результаты, но находятся в другом порядке LINQ. Я понимаю, что переупорядочение некоторых предметов приведет к разным результатам, и меня это не касается. Основная моя забота заключается в том, что при получении одинаковых результатов заказ может повлиять на производительность. И не только на 2 вызовах LINQ, которые я сделал (OrderBy, Where), но и на любые вызовы LINQ.

Это будет зависеть от используемого поставщика LINQ. Для LINQ to Objects это может иметь огромное значение. Предположим, что у нас есть:

 var query = myCollection.OrderBy(item => item.CreatedDate) .Where(item => item.Code > 3); var result = query.Last(); 

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

Сравните это с обратной обработкой, сначала фильтруя:

 var query = myCollection.Where(item => item.Code > 3) .OrderBy(item => item.CreatedDate); var result = query.Last(); 

На этот раз мы заказываем только отфильтрованные результаты, которые в примере примера «только один элемент, соответствующий фильтру» будет намного более эффективным – как во времени, так и в пространстве.

Это также может повлиять на правильность выполнения запроса или нет. Рассматривать:

 var query = myCollection.Where(item => item.Code != 0) .OrderBy(item => 10 / item.Code); var result = query.Last(); 

Это прекрасно – мы знаем, что мы никогда не разделим на 0. Но если мы выполним упорядочение перед фильтрацией, запрос вызовет исключение.

Да.

Но именно эта разница в производительности зависит от того, как базовое дерево выражений оценивается поставщиком LINQ.

Например, ваш запрос может выполняться быстрее во второй раз (сначала с предложением WHERE) для LINQ-to-XML, но быстрее в первый раз для LINQ-to-SQL.

Чтобы точно узнать, что такое разница в производительности, вы, скорее всего, захотите профилировать свое приложение. Однако, несмотря на такие вещи, преждевременная оптимизация обычно не стоит усилий – вы можете найти проблемы, отличные от производительности LINQ, более важные.

В вашем конкретном примере это может повлиять на производительность.

Первый запрос: вашему вызову OrderBy необходимо выполнить итерацию по всей исходной последовательности, включая те элементы, где Code равен 3 или меньше. Предложение Where также требует итерации всей упорядоченной последовательности.

Второй запрос: вызов Where ограничивает последовательность только теми пунктами, где Code больше 3. Для вызова OrderBy требуется только перемещение приведенной последовательности, возвращаемой вызовом Where .

В Linq-To-Objects:

Сортировка выполняется довольно медленно и использует память O(n) . Where с другой стороны, относительно быстро и использует постоянную память. Итак, Where сначала будет быстрее, а для больших коллекций значительно быстрее.

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

Очевидно, что результаты должны быть одинаковыми …

Обратите внимание, что это на самом деле не так – в частности, следующие две строки будут давать разные результаты (для большинства поставщиков / наборов данных):

 myCollection.OrderBy(o => o).Distinct(); myCollection.Distinct().OrderBy(o => o); 

Стоит отметить, что вы должны быть осторожны при рассмотрении того, как оптимизировать запрос LINQ. Например, если вы используете декларативную версию LINQ для выполнения следующих действий:

 public class Record { public string Name { get; set; } public double Score1 { get; set; } public double Score2 { get; set; } } var query = from record in Records order by ((record.Score1 + record.Score2) / 2) descending select new { Name = record.Name, Average = ((record.Score1 + record.Score2) / 2) }; 

Если по какой-то причине вы решили «оптимизировать» запрос, сначала сохраняя среднее значение в переменной, вы не получите желаемых результатов:

 // The following two queries actually takes up more space and are slower var query = from record in Records let average = ((record.Score1 + record.Score2) / 2) order by average descending select new { Name = record.Name, Average = average }; var query = from record in Records let average = ((record.Score1 + record.Score2) / 2) select new { Name = record.Name, Average = average } order by average descending; 

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

Это зависит от релевантности. Предположим, что если у вас очень мало элементов с кодом = 3, следующий порядок будет работать с небольшим набором коллекций, чтобы получить заказ по дате.

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

Таким образом, в обоих случаях будет разница в производительности

  • «Диспетчер задач» для Firefox?
  • Самый быстрый способ суммирования целых чисел в текстовом файле
  • SSD и нетбук - замораживание во время ввода-вывода
  • Какой самый быстрый способ изменить ключ элемента внутри std :: map
  • Когда JVM будет использовать встроенные средства
  • Если профайлер не является ответом, какие у нас есть другие варианты?
  • Что заставляет JNI звонить медленно?
  • Более быстрые альтернативы отражению Java
  • Наиболее эффективная библиотека примитивных библиотек Java
  • Является ли String.Format таким же эффективным, как StringBuilder
  • Влияние производительности использования instanceof в Java
  • Interesting Posts

    Как испустить сигнал кросс-нитки в Qt?

    для цикла в Java запускается 3 раза, прежде чем принимать следующий ввод

    Какова цель подстановочных знаков и как они отличаются от дженериков?

    Что означает «L» в конце целочисленного литерала?

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

    CSS Обоснуйте текст, заполните пробел точками

    Аргументы для основного в C

    Разница по месяцам Java

    Несоответствие между процессором «top» и процентом использования процессора

    Есть ли стандарт для хранения нормализованных номеров телефонов в базе данных?

    форма андроида с нижним ходом

    Добавить значение в пустой вектор в R?

    Обновление с 32-битного Windows7 до 64-битного WIn7, чтобы соответствовать 64-разрядному процессору

    Удаление потерянных iTunes песен с жесткого диска

    Узнайте, какой процесс блокирует файл или папку в Windows

    Давайте будем гением компьютера.