Будет Сначала (), выполняют OrderBy ()?

Есть ли любая разница в (асимптотической) производительности между

var a = Orders.OrderBy(order => order.Date).First()

и

var y = Orders.Where(order => order.Date == Orders.Min(x => x.Date)).ToList();

т.е. будет Сначала (), выполняют OrderBy ()? Я предполагаю нет. MSDN заявляет, что перечисление набора через foreach och GetEnumerator делает, но формулировка не исключает другие расширения.

10
задан Martin 16 March 2010 в 17:40
поделиться

4 ответа

Несколько вещей:

  • OrderBy () упорядочивает от малого к большему, поэтому две альтернативы возвращают разные элементы
  • Where () обычно ленив, поэтому ваше второе выражение на самом деле не работает делать какие-либо вычисления - только после того, как они будут использованы.
  • В принципе, рассматриваемое поведение зависит от поставщика запроса. Например, вы действительно можете ожидать, что поставщик запросов sql-server linq будет справляться с этим иначе, чем поставщик запросов IEnumerable. Поставщик запросов может выбрать, чтобы возвращаемое значение «OrderBy» было достаточно специализированным, чтобы вызов First () на нем распознал (либо во время компиляции, либо во время выполнения), что он работает с упорядоченным перечислимым, и вместо этого сортировки выбирает возврат (первого) минимального элемента.
  • Специально для поставщика IEnumerable , OrderBy возвращает перечислимое значение, которое полностью буферизует и сортирует ввод каждый раз, когда извлекается первый элемент - так что в общем базовый случай Linq-to-objects, OrderBy (). First () сравним с OrderBy (). ToArray () .

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

11
ответ дан 3 December 2019 в 17:19
поделиться

Метод First выполнит OrderBy (то есть при условии, что метод First выполнен, конечно). Когда метод First извлечет первый элемент из результата OrderBy, ему придется отсортировать все элементы, чтобы выяснить, какой из них первый.

В зависимости от того, где и как выполняется запрос (т.е. если механизм запросов не может оптимизировать его), второй запрос может работать довольно плохо. Если Orders.Max оценивается один раз для каждого товара в Orders, это становится операцией O(n*n), что довольно плохо.

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

6
ответ дан 3 December 2019 в 17:19
поделиться

Сначала вернет первую запись переданного ему IEnumerable. Поскольку IEnumerable, переданный в First , является результатом OrderBy , ваш вопрос можно перефразировать на «Работает ли OrderBy », и да, это так.

Первый не может отложить выполнение OrderBy , потому что он сразу возвращает результат. Например:

        var numbers = new int[] { 9, 3, 4, 6, 7 };

        var num = numbers.First();
        Console.WriteLine(num);

        num = numbers.OrderBy(i => i).First();
        Console.WriteLine(num);

        Console.ReadLine();
6
ответ дан 3 December 2019 в 17:19
поделиться

Не работает. ЭТО СКАЗАНО - естественно, что orderby будет выполняться в тот момент, когда кто-то попытается получить первый элемент.

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

0
ответ дан 3 December 2019 в 17:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: