<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Performance Quiz #13 -- Linq to SQL compiled query cost -- solution</title><link>http://blogs.msdn.com/ricom/archive/2008/01/14/performance-quiz-13-linq-to-sql-compiled-query-cost-solution.aspx</link><description>Well is there really a "solution" at all in general? This particular case I think I constrained enough that you can claim an answer but does it generalize? Let's look at what I got first, the raw results are pretty easy to understand. The experiment I</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Geek Lectures - Things geeks should know about &amp;raquo; Blog Archive   &amp;raquo;  Performance Quiz #13 &amp;#8212; Linq to SQL compiled query cost &amp;#8212; solution</title><link>http://blogs.msdn.com/ricom/archive/2008/01/14/performance-quiz-13-linq-to-sql-compiled-query-cost-solution.aspx#7110182</link><pubDate>Mon, 14 Jan 2008 21:08:51 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7110182</guid><dc:creator>Geek Lectures - Things geeks should know about » Blog Archive   »  Performance Quiz #13 — Linq to SQL compiled query cost — solution</dc:creator><description>&lt;p&gt;PingBack from &lt;a rel="nofollow" target="_new" href="http://geeklectures.info/2008/01/14/performance-quiz-13-linq-to-sql-compiled-query-cost-solution/"&gt;http://geeklectures.info/2008/01/14/performance-quiz-13-linq-to-sql-compiled-query-cost-solution/&lt;/a&gt;&lt;/p&gt;</description></item><item><title>re: Performance Quiz #13 -- Linq to SQL compiled query cost -- solution</title><link>http://blogs.msdn.com/ricom/archive/2008/01/14/performance-quiz-13-linq-to-sql-compiled-query-cost-solution.aspx#7110413</link><pubDate>Mon, 14 Jan 2008 21:34:50 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7110413</guid><dc:creator>Peter Ritchie</dc:creator><description>&lt;p&gt;I, for one, would be interested in seeing the code associated with this. -- Thanks&lt;/p&gt;
</description></item><item><title>re: Performance Quiz #13 -- Linq to SQL compiled query cost -- solution</title><link>http://blogs.msdn.com/ricom/archive/2008/01/14/performance-quiz-13-linq-to-sql-compiled-query-cost-solution.aspx#7110441</link><pubDate>Mon, 14 Jan 2008 21:37:15 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7110441</guid><dc:creator>Peter Ritchie</dc:creator><description>&lt;p&gt;I think the results that others have posted in the previous post and their differences shows that it depends on the query, the database and how you implement it. &amp;nbsp;Whether or not to use (or not use) a compiled query should be based on observed metrics.&lt;/p&gt;
</description></item><item><title>re: Performance Quiz #13 -- Linq to SQL compiled query cost -- solution</title><link>http://blogs.msdn.com/ricom/archive/2008/01/14/performance-quiz-13-linq-to-sql-compiled-query-cost-solution.aspx#7110524</link><pubDate>Mon, 14 Jan 2008 21:45:23 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7110524</guid><dc:creator>ricom</dc:creator><description>&lt;P&gt;It's just two nested loops around the queries I gave in the problem statement. &amp;nbsp;The timer goes around the whole thing. &amp;nbsp;Couldn't be any dumber.&lt;/P&gt;
&lt;P&gt;start timer&lt;/P&gt;
&lt;P&gt;for (j=0;j&amp;lt;batches;j++)&lt;/P&gt;
&lt;P&gt;&amp;nbsp; compile query&lt;/P&gt;
&lt;P&gt;&amp;nbsp; for (i=0;i&amp;lt;runs;i++)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; create new data context&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; run query in new context&lt;/P&gt;
&lt;P&gt;stop timer&lt;/P&gt;
&lt;P&gt;print number of selects and time etc.&lt;/P&gt;
&lt;P&gt;batches*runs always = 5000&lt;/P&gt;
&lt;P&gt;In the uncompiled case it really doesn't matter how many in each batch because the same code runs the same number of times plus or minus some loop overhead.&lt;/P&gt;
&lt;P&gt;start timer&lt;/P&gt;
&lt;P&gt;for (j=0;j&amp;lt;batches;j++)&lt;/P&gt;
&lt;P&gt;&amp;nbsp; for (i=0;i&amp;lt;runs;i++)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; create new data context&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; run query in new context&lt;/P&gt;
&lt;P&gt;stop timer&lt;/P&gt;
&lt;P&gt;print number of selects and time etc.&lt;/P&gt;</description></item><item><title>re: Performance Quiz #13 -- Linq to SQL compiled query cost -- solution</title><link>http://blogs.msdn.com/ricom/archive/2008/01/14/performance-quiz-13-linq-to-sql-compiled-query-cost-solution.aspx#7110594</link><pubDate>Mon, 14 Jan 2008 21:54:44 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7110594</guid><dc:creator>ricom</dc:creator><description>&lt;P&gt;Peter writes: "I think the results that others have posted in the previous post and their differences shows that it depends on the query, the database and how you implement it. &amp;nbsp;Whether or not to use (or not use) a compiled query should be based on observed metrics."&lt;/P&gt;
&lt;P&gt;Well you'll never get me to disagree with "you should make your choice based on observed metrics." &amp;nbsp;&lt;/P&gt;
&lt;P&gt;I think what you'll find is that you break even very easily so you'll end up making your choice on the basis of: &amp;nbsp;&lt;/P&gt;
&lt;P&gt;1) is there any re-use at all&lt;/P&gt;
&lt;P&gt;2) how much uglier is the compiled code pattern and is the benefit worth the hassle&lt;/P&gt;
&lt;P&gt;The more complicated the query, the greater the benefits of not having to re-analyze it. &amp;nbsp;&lt;/P&gt;
&lt;P&gt;On the other hand, slower connections and/or more data processing will tend to make all the Linq overheads smaller by proportion, to the point where it could all be moot.&lt;/P&gt;
&lt;P&gt;But the point here is to illustrate that, unlike other compilation methods, this one has very modest overhead because the compiled path is nearly the same as the uncompiled path. &amp;nbsp;There isn't a seperate "compilation" vs. "interpretation" process like in say regular expressions.&lt;/P&gt;
&lt;P&gt;Or, said yet another way, you actually always compile the query. &amp;nbsp;The only question is, do you save the results of compilation or not?&lt;/P&gt;</description></item><item><title>re: Performance Quiz #13 -- Linq to SQL compiled query cost -- solution</title><link>http://blogs.msdn.com/ricom/archive/2008/01/14/performance-quiz-13-linq-to-sql-compiled-query-cost-solution.aspx#7110769</link><pubDate>Mon, 14 Jan 2008 22:18:07 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7110769</guid><dc:creator>Brian</dc:creator><description>&lt;p&gt;Umm, what does the &amp;quot;In fact, the magic number for this particular query is about 1.5 average uses to break even.&amp;quot; tell me? Isn't that discrete, you can either run it once or twice. How do I run this query 1.5 times? The 1.5 average is pretty useless in this case. &lt;/p&gt;
</description></item><item><title>re: Performance Quiz #13 -- Linq to SQL compiled query cost -- solution</title><link>http://blogs.msdn.com/ricom/archive/2008/01/14/performance-quiz-13-linq-to-sql-compiled-query-cost-solution.aspx#7111649</link><pubDate>Tue, 15 Jan 2008 00:09:13 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7111649</guid><dc:creator>Paul</dc:creator><description>&lt;p&gt;It tells you that when your code is executed, if the average number of times a particular query is run is &amp;gt;1.5, then you should consider using compiled queries.&lt;/p&gt;
</description></item><item><title>re: Performance Quiz #13 -- Linq to SQL compiled query cost -- solution</title><link>http://blogs.msdn.com/ricom/archive/2008/01/14/performance-quiz-13-linq-to-sql-compiled-query-cost-solution.aspx#7111716</link><pubDate>Tue, 15 Jan 2008 00:16:35 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7111716</guid><dc:creator>Peter Ritchie</dc:creator><description>&lt;p&gt;RE: &amp;quot;...break even very easily...&amp;quot;&lt;/p&gt;
&lt;p&gt;This has to do with (I'm assuming) having to change the code from being used uncompiled to compiled (and/or vice versa)...&lt;/p&gt;
&lt;p&gt;Unfortunately the complexity of anonymous types and the way LINQ is compiled into IL makes it really hard to separate the query into it's own concern. &amp;nbsp;I.e. it's hard, and not as efficient as compiled directly, to get a LINQ query into a delegate that you could then use either to compile/execute or just execute. &amp;nbsp;So, it's hard to push whether a LINQ statement is compiled or not into a policy that is chosen at runtime.&lt;/p&gt;
&lt;p&gt;Ideally you would do something like this:&lt;/p&gt;
&lt;p&gt;MyClass myClass = new MyClass(new CompileLinqStrategy());&lt;/p&gt;
&lt;p&gt;//...&lt;/p&gt;
&lt;p&gt;// somewhere in MyClass:&lt;/p&gt;
&lt;p&gt;Expression&amp;lt;Func&amp;lt;DataContext, SomeType&amp;gt;&amp;gt; expression = (NorthwindDataContext nw) =&amp;gt; (from ...);&lt;/p&gt;
&lt;p&gt;var results = linqStrategy.Invoke(expression);&lt;/p&gt;
&lt;p&gt;foreach(var result in results)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt; // do something with result&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;CompiledLinqStrategy and UncompiledLinqStrategy would simply execute the expression (CompiledLinqStrategy would compile it first, of course).&lt;/p&gt;
&lt;p&gt;Whether or not the expression is compiled or not has been completely separated from the code that uses the LINQ statement and therefore the LINQ statement need not change to switch from uncompiled to compiled and the problem of the code breaking due to this change is eliminated.&lt;/p&gt;
&lt;p&gt;Unfortunately the C# compiler compiles a LINQ statement into much more efficient IL code than you could write manually to execute the expression, so my guess is you'd end up eating most of the performance gains.&lt;/p&gt;
&lt;p&gt;...we need a memberof (and infoof) in C#...&lt;/p&gt;
</description></item><item><title>re: Performance Quiz #13 -- Linq to SQL compiled query cost -- solution</title><link>http://blogs.msdn.com/ricom/archive/2008/01/14/performance-quiz-13-linq-to-sql-compiled-query-cost-solution.aspx#7112888</link><pubDate>Tue, 15 Jan 2008 02:21:13 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7112888</guid><dc:creator>Chabster</dc:creator><description>&lt;p&gt;&amp;gt; the main purpose of that compiled query object is to have an object, of the correct type, that also has the correct lifetime&lt;/p&gt;
&lt;p&gt;If there was some mechanism to reference anonymous types like this:&lt;/p&gt;
&lt;p&gt;Expression&amp;lt;Func&amp;lt;?&amp;gt;&amp;gt; expr = from o in nw.Orders select new { OrderID = o.OrderID, CustomerID = o.CustomerID, EmployeeID = o.EmployeeID, ShippedDate = o.ShippedDate };&lt;/p&gt;
&lt;p&gt;there would be no need for compilation you think?&lt;/p&gt;
&lt;p&gt;And what is the difference between CompiledQuery.Compile and the following:&lt;/p&gt;
&lt;p&gt;public static Func&amp;lt;TArg0, TResult&amp;gt; MyCompile&amp;lt;TArg0, TResult&amp;gt;(Expression&amp;lt;Func&amp;lt;TArg0, TResult&amp;gt;&amp;gt; query) where TArg0 : DataContext {&lt;/p&gt;
&lt;p&gt;			return(query.Compile());&lt;/p&gt;
&lt;p&gt;		}&lt;/p&gt;
&lt;p&gt;var myQuery = MyCompile((Northwind nwDb) =&amp;gt; (from o in nwDb.Orders select new { OrderID_C = o.OrderID, CustomerID = o.CustomerID, EmployeeID = o.EmployeeID, ShippedDate = o.ShippedDate }));&lt;/p&gt;
&lt;p&gt;I suppose where TArg0 : DataContext restriction might be very important! It allows to introspect TArg0 and emit direct code to manipulate it!&lt;/p&gt;
</description></item><item><title>LINQ query versus compiled LINQ query</title><link>http://blogs.msdn.com/ricom/archive/2008/01/14/performance-quiz-13-linq-to-sql-compiled-query-cost-solution.aspx#7113835</link><pubDate>Tue, 15 Jan 2008 03:55:11 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7113835</guid><dc:creator>Blog</dc:creator><description>&lt;p&gt;LINQ query versus compiled LINQ query&lt;/p&gt;
</description></item><item><title>LINQ query versus compiled LINQ query</title><link>http://blogs.msdn.com/ricom/archive/2008/01/14/performance-quiz-13-linq-to-sql-compiled-query-cost-solution.aspx#7113851</link><pubDate>Tue, 15 Jan 2008 03:58:45 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7113851</guid><dc:creator>Pawel Pabich's blog</dc:creator><description>&lt;p&gt;LINQ query versus compiled LINQ query&lt;/p&gt;
</description></item><item><title>re: Performance Quiz #13 -- Linq to SQL compiled query cost -- solution</title><link>http://blogs.msdn.com/ricom/archive/2008/01/14/performance-quiz-13-linq-to-sql-compiled-query-cost-solution.aspx#7114812</link><pubDate>Tue, 15 Jan 2008 05:54:51 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7114812</guid><dc:creator>Paul</dc:creator><description>&lt;p&gt;&amp;gt;Any Linq to SQL user can choose how much or how little caching is done. &amp;nbsp;They control the lifetime, they can choose an easy mechanism (e.g. stuff it in a static variable forever) or a complicated recycling method depending on their needs.&lt;/p&gt;
&lt;p&gt;Rico, can you give us an example of how to control the lifetime of this particular compiled query? The resulting compiled query is an anonymous type. This generally limits its usage to the scope of the method that created it. It seems that the caveat is that there's a lot less flexibility in controlling the lifetime of a compiled query based on anonymous types.&lt;/p&gt;
</description></item><item><title>re: Performance Quiz #13 -- Linq to SQL compiled query cost -- solution</title><link>http://blogs.msdn.com/ricom/archive/2008/01/14/performance-quiz-13-linq-to-sql-compiled-query-cost-solution.aspx#7118865</link><pubDate>Tue, 15 Jan 2008 19:39:58 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7118865</guid><dc:creator>ricom</dc:creator><description>&lt;p&gt;You have to use the more formal syntax and store the thing in a static or something like that. &amp;nbsp;Or store it as a member of some other helper type with suitable lifetime.&lt;/p&gt;
&lt;p&gt;In this case I was able to use the simpler 'var' syntax because I had a synthetic lifetime. Normally you don't get such a luxury.&lt;/p&gt;
&lt;p&gt;I think you could stuff it in a local, using var, then use intellisense to see the exact type, and make something of that type for instance.&lt;/p&gt;
</description></item><item><title>re: Performance Quiz #13 -- Linq to IQueryable performance</title><link>http://blogs.msdn.com/ricom/archive/2008/01/14/performance-quiz-13-linq-to-sql-compiled-query-cost-solution.aspx#7534119</link><pubDate>Fri, 08 Feb 2008 07:50:25 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7534119</guid><dc:creator>michael.plavnik</dc:creator><description>&lt;p&gt;Rico, I was itereseted in performance of compiler generated code against IQueryable&amp;lt;&amp;gt;. So I wrote simplistic provider that creates new queryable every time. Query buildup (no query translation) below takes about 70 microseconds on my Intel Core2 6600@2.4GHz machine. It is roughly equivalent to the time it takes to query first 10 orders from Nortwind database on the same machine with SqlDataReader.&lt;/p&gt;
&lt;p&gt;var q = from a in source&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;group a by a[0] into g &amp;nbsp;where g.Key == 'a'&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;from x in g &amp;nbsp;select x;&lt;/p&gt;
&lt;p&gt;10,000 queries top per processor would seem like very small number for high end data solutions, isn't it?! There is also an issue of holding transaction open for longer then necessary, which then need to be carefuly avoided in code. &lt;/p&gt;
&lt;p&gt;Better support for compiled queries looks like a must have.&lt;/p&gt;
</description></item><item><title>10 Tips to Improve your LINQ to SQL Application Performance</title><link>http://blogs.msdn.com/ricom/archive/2008/01/14/performance-quiz-13-linq-to-sql-compiled-query-cost-solution.aspx#8459287</link><pubDate>Mon, 05 May 2008 05:17:08 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8459287</guid><dc:creator>History Viewer</dc:creator><description>&lt;p&gt;10 Tips to Improve your LINQ to SQL Application Performance&lt;/p&gt;
</description></item><item><title>Solving common problems with Compiled Queries in Linq to Sql for high demand ASP.NET websites</title><link>http://blogs.msdn.com/ricom/archive/2008/01/14/performance-quiz-13-linq-to-sql-compiled-query-cost-solution.aspx#9018851</link><pubDate>Mon, 27 Oct 2008 22:25:31 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9018851</guid><dc:creator>Omar AL Zabir blog on ASP.NET Ajax and .NET 3.5</dc:creator><description>&lt;p&gt;If you are using Linq to SQL, instead of writing regular Linq Queries, you should be using Compiled Queries&lt;/p&gt;
</description></item><item><title>Solving common problems with Compiled Queries in Linq to Sql for high demand ASP.NET websites</title><link>http://blogs.msdn.com/ricom/archive/2008/01/14/performance-quiz-13-linq-to-sql-compiled-query-cost-solution.aspx#9018862</link><pubDate>Mon, 27 Oct 2008 22:32:15 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9018862</guid><dc:creator>Omar AL Zabir blog on ASP.NET Ajax and .NET 3.5</dc:creator><description>&lt;p&gt;If you are using Linq to SQL, instead of writing regular Linq Queries, you should be using Compiled Queries&lt;/p&gt;
</description></item><item><title>10 Tips to Improve your LINQ to SQL Application Performance</title><link>http://blogs.msdn.com/ricom/archive/2008/01/14/performance-quiz-13-linq-to-sql-compiled-query-cost-solution.aspx#9059283</link><pubDate>Tue, 11 Nov 2008 08:07:17 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9059283</guid><dc:creator>吴明浩</dc:creator><description>&lt;p&gt;Heythere,backagain.InmyfirstpostaboutLINQItriedtoprovideabrief(okay,bitdetailed)in...&lt;/p&gt;
</description></item></channel></rss>