views:

71

answers:

2

I've just recently started using LINQ on a daily basis. I've read quite a lot about L2E queries should be compiled to improve performance using the following:

CompiledQuery.Compile(query);

Using LINQ-To-Entities 4.0 I ran a query 10 times uncompiled and then compiled and yielded the following results in seconds:

// Sample Query
from u in ctx.Users orderby u.Id, u.Username select u

Uncompiled  Compiled
---------------------
0.295       0.2946174
0.024       0.0220462
0.008       0.0060126
0.013       0.0210441
0.007       0.010021
0.011       0.010021
0.008       0.0060126
0.009       0.0070147
0.008       0.0060126

As you can see there's not a real big difference in the times from my small test. There is slower time for the first call, and then both speed up (implying compilation/caching). Can anyone provide insight to this?

A: 

You're probably not disposing the context. Queries are cached in the context, but compiling them allows you to use them across multiple contexts. Hard to say for sure since you don't actually show your full code.

Craig Stuntz
Nope, it was wrapped in a `using` statement inside of a method that was called when a button was clicked (I don't have the code with me but I know for a fact I was disposing it).
TheCloudlessSky
You're going to have to post code, then, if you want an answer.
Craig Stuntz
+1  A: 

From what I can gather, it has about the same benefit of hard-coded SQL queries with embedded parameters to SQL queries using named parameters: The system can recognize that they're all the same and use the same query plan.

For instance, if you were to simply inline the expression above, it will probably work just as well as compiling it if you're always passing in the same ctx.Users object. However, if you had several user repositories of the same type and were planning on using that order by on all of them, it would be a good idea to compile the query once and use parameters to access it.

When researching this, I took a look at how a LINQ query is formed in IL: a new Func<> delegate is created for just about every clause in your LINQ query every time you call it. For that reason alone, I imagine that compiling a query will be better for your system as far as memory thrashing goes.

mattdekrey
Yeah I realized that SQL server is obviously doing some caching of the query since the un-compiled version is having the same performance issue for the first time they query is run. After some more testing today on my home machine, I was able to see that on average compiled queries run 0.001 seconds quicker in my environment. It's not much, but interesting none the less.
TheCloudlessSky