Действительно ли возможно скомпилировать запрос для linq к объектам

У меня есть linq к запросу объектов в рекурсивном цикле и боящийся, когда объекты приблизятся к более затем 1000 и более затем 100 пользователей сайта - мой веб-сайт повредится. так это возможный скомпилировать linq в запрос объектов.

Запрос linq делает ничто больше затем не находит прямых детей узла.

5
задан Luke101 16 April 2010 в 00:32
поделиться

2 ответа

Чтобы понять, почему концепция компиляции на самом деле не имеет смысла для запросов LINQ to Object, полезно понять, как LINQ реализовано. Во-первых, должно быть ясно, что запросы LINQ, написанные с плавным синтаксисом, преобразуются компилятором C # в эквивалентный синтаксис вызова методов во время времени компиляции независимо от того, какой вариант LINQ вы используете:

from person in people
where person.Age < 18
select person.Name
// will be converted to:
people.Where(person => person.Age < 18).Select(person => person.Name)

С этого момента далее запрос LINQ представляет собой набор вызовов методов, принимающих некоторые аргументы и обычно преобразующих объект IEnumerable в другой объект IEnumerable . Отложенное выполнение, которое отличается от компиляции, просто достигается за счет того, что не берется какой-либо объект из исходного IEnumerable , пока вы не перейдете к выходу IEnumerable . По сути, методы с отложенным выполнением оперируют своими аргументами символически, не затрагивая исходную коллекцию, создавая генератор, который запрашивает данные по своему усмотрению.

Имея это в виду, взгляните на лямбда-выражение person => person.Age <18 в приведенном выше выражении.Он принимает объект Person и возвращает bool . Лямбда-выражения нетипизированы; их можно рассматривать как деревья выражений или анонимные методы в зависимости от контекста, из которого выводится их тип. В этом случае тип определяется из типа параметра метода расширения Where . Вот где проявляется различие между LINQ to SQL и LINQ to Object. В LINQ to Objects метод Where просто принимает Func в отличие от Expression > . По сути, это означает, что в LINQ to Objects компилятор C # компилирует лямбда-выражение до анонимного метода и генерирует IL во время компиляции и передает делегата этому методу в Where .

В других вариантах LINQ, таких как LINQ to SQL, лямбда не компилируется в IL. Вместо этого компилятор создает объект дерева выражения из лямбда-выражения и передает дерево выражения в методы LINQ. Методы LINQ используют эти деревья выражений для построения модели запросов. Когда запрос выполняется, объектная модель, созданная для представления запроса с использованием деревьев выражений, будет преобразована в другую вещь (в зависимости от используемого варианта LINQ), например SQL-операторы в LINQ to SQL, для выполнения в базе данных. Этот процесс преобразования выполняется во время выполнения, и это то, что мы называем компиляцией запросов LINQ .

Подводя итог, вопрос состоит в том, чтобы скомпилировать что ? Причина, по которой LINQ to Object не требует компиляции во время выполнения, заключается в том, что он изначально не в формате дерева выражений; это уже ИЛ.

Вам почти никогда не нужно беспокоиться о производительности LINQ to Objects по сравнению с обычным циклом.

16
ответ дан 18 December 2019 в 10:43
поделиться

Как и во всех случаях оптимизации, беспокойтесь об этом, когда доберетесь туда. С очень высокой вероятностью, если вы когда-нибудь подключите более 100 пользователей одновременно, ваше узкое место будет в совершенно другом месте.

0
ответ дан 18 December 2019 в 10:43
поделиться
Другие вопросы по тегам:

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