Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Do you mean in terms of a query expression, or what the query does behind the scenes?</p> <p>Query expressions are expanded into "normal" C# first. For example:</p> <pre><code>var query = from x in source where x.Name == "Fred" select x.Age; </code></pre> <p>is translated to:</p> <pre><code>var query = source.Where(x =&gt; x.Name == "Fred") .Select(x =&gt; x.Age); </code></pre> <p>The exact <em>meaning</em> of this depends on the type of <code>source</code> of course... in LINQ to Objects, it typically implements <code>IEnumerable&lt;T&gt;</code> and the <code>Enumerable</code> extension methods come into play... but it could be a different set of extension methods. (LINQ to SQL would use the <code>Queryable</code> extension methods, for example.)</p> <p>Now, suppose we <em>are</em> using LINQ to Objects... after extension method expansion, the above code becomes:</p> <pre><code>var query = Enumerable.Select(Enumerable.Where(source, x =&gt; x.Name == "Fred"), x =&gt; x.Age); </code></pre> <p>Next the implementations of <code>Select</code> and <code>Where</code> become important. Leaving out error checking, they're <em>something</em> like this:</p> <pre><code>public static IEnumerable&lt;T&gt; Where&lt;T&gt;(this IEnumerable&lt;T&gt; source, Func&lt;T, bool&gt; predicate) { foreach (T element in source) { if (predicate(element)) { yield return element; } } } public static IEnumerable&lt;TResult&gt; Select&lt;TSource, TResult&gt; (this IEnumerable&lt;TSource&gt; source, Func&lt;TSource, TResult&gt; selector) { foreach (TSource element in source) { yield return selector(element); } } </code></pre> <p>Next there's the expansion of iterator blocks into state machines, which I won't go into here but which I have an <a href="http://csharpindepth.com/Articles/Chapter6/IteratorBlockImplementation.aspx" rel="nofollow noreferrer">article about</a>.</p> <p>Finally, there's the conversion of lambda expressions into extra methods + appropriate delegate instance creation (or expression trees, depending on the signatures of the methods called).</p> <p>So basically LINQ uses a <em>lot</em> of clever features of C#:</p> <ul> <li>Lambda expression conversions (into delegate instances and expression trees)</li> <li>Extension methods</li> <li>Type inference for generic methods</li> <li>Iterator blocks</li> <li>Often anonymous types (for use in projections)</li> <li>Often implicit typing for local variables</li> <li>Query expression translation</li> </ul> <p>However, the individual operations are quite simple - they don't perform indexing etc. Joins and groupings are done using hash tables, but straightforward queries like "where" are just linear. Don't forget that LINQ to Objects usually just treats the data as a forward-only readable sequence - it can't do things like a binary search.</p> <p>Normally I'd expect hand-written queries to be marginally faster than LINQ to Objects as there are fewer layers of abstraction, but they'll be less readable and the performance difference usually won't be significant.</p> <p>As ever for performance questions: when in doubt, measure!</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload