Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to compile a query for linq-to-objects

I have a linq to objects query in a recursive loop and afraid when the objects approach more then 1000 and a have more then 100 users on the site -- my website will break. so is it possible to compile a linq to objects query.

The linq query does nothing more then find the direct children of a node.

like image 413
Luke101 Avatar asked Apr 16 '10 00:04

Luke101


1 Answers

To see why the concept of compilation doesn't really make sense for LINQ to Object queries, it's useful to understand how LINQ is implemented. First, it should be clear that LINQ queries written in fluent syntax are converted to the equivalent method call syntax at compile time by the C# compiler regardless of the variant of LINQ you're using:

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)

From now on, the LINQ query is basically a set of method calls taking some arguments and usually transforming an IEnumerable<T> object to another IEnumerable<T> object. Deferred execution, which is a different from compilation, is simply achieved by not taking any object from the original IEnumerable<T> until you're traversing the output IEnumerable<T>. Basically, methods with deferred execution are operating on their arguments symbolically without touching the original collection, building up a generator that queries stuff as you like.

With that in mind, take a look at the lambda expression person => person.Age < 18 in the above expression. It takes a Person object and returns a bool. Lambda expressions are untyped; they can be treated as expression trees or anonymous methods depending on the context their type is inferred from. In this case, the type is inferred from the parameter type of the Where extension method. This is where the distinction of LINQ to SQL and LINQ to Object comes up. In LINQ to Objects, the Where method simply takes Func<Person, bool> as opposed to Expression<Func<Person, bool>>. This essentially means that in LINQ to Objects, the C# compiler compiles the lambda expression down to an anonymous method and generates the IL at compile time and passes a delegate to that method to Where.

In other LINQ flavors, like LINQ to SQL, the lambda is not compiled to IL. Instead, the compiler builds up an expression tree object out of the lambda expression and passes the expression tree to LINQ methods. LINQ methods use these expression trees to build up a model for querying stuff. When the query is being run, the object model built to represent the query using the expression trees will be transformed to another thing (depending on the LINQ variant used) like SQL statements in LINQ to SQL in order to get executed on the database. This transformation process is done at runtime and it's what we call compilation of LINQ queries.

To sum up, the question is compile to what? The reason LINQ to Object doesn't need compilation at runtime is that it's not in expression tree format in the first place; it's already IL.

You almost never need to worry about the performance of LINQ to Objects in comparison to normal looping.

like image 95
mmx Avatar answered Nov 20 '22 13:11

mmx