Можно ли скомпилировать запрос для linq-to-objects - PullRequest
5 голосов
/ 16 апреля 2010

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

Запрос linq ничего не делает, кроме как находит прямых потомков узла.

Ответы [ 2 ]

16 голосов
/ 16 апреля 2010

Чтобы понять, почему концепция компиляции не имеет смысла для запросов 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<T> в другой объект IEnumerable<T>. Отложенное выполнение, которое отличается от компиляции, просто достигается, если не брать какой-либо объект из исходного IEnumerable<T> до тех пор, пока вы не пройдете вывод IEnumerable<T>. По сути, методы с отложенным выполнением работают со своими аргументами символически, не затрагивая исходную коллекцию, создавая генератор, который запрашивает материал как вам угодно.

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

0 голосов
/ 16 апреля 2010

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

...