Поделиться через


Сложность метода LINQ OrderBy.First{OrDefault} увеличилась.

Изменение реализации OrderBy.First<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>) и OrderBy.FirstOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>) привело к увеличению сложности операции.

Описание изменения

В .NET Core 1.x — 3.x вызов OrderBy или OrderByDescending с последующим вызовом First<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>) или FirstOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>) имеет сложность O(N). Так как требуется только первый (или по умолчанию) элемент, для его поиска требуется только одно перечисление. Однако предикат, переданный First<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>) или FirstOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>), вызывается ровно N раз, где N — длина последовательности.

В .NET 5 и более поздних версиях было внесено изменение, так что вызов OrderBy или OrderByDescending, за которым следует First<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>) или FirstOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>), работает с O(N log N) сложностью вместо O(N) сложности. Однако предикат, предоставленный для First<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>) или FirstOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>), может вызываться меньше раз, что более важно для общей производительности.

Замечание

Это изменение соответствует реализации и сложности операции в .NET Framework.

Причина изменения

Преимущество меньшего количества обращений к предикату перевешивает более низкую общую сложность, поэтому реализация, введенная в .NET Core 1.0, была отменена. Для получения дополнительной информации обратите внимание на этот вопрос dotnet/runtime.

Представленная версия

5,0

Действия со стороны разработчика не требуются.

Затронутые API