title: Why is LINQ .Where(predicate).First() faster than .First(predicate)?
body: <p>I am doing some performance tests and noticed that a LINQ expression like</p>
  
  <pre><code>result = list.First(f =&gt; f.Id == i).Property
  </code></pre>
  
  <p>is slower than</p>
  
  <pre><code>result = list.Where(f =&gt; f.Id == i).First().Property
  </code></pre>
  
  <p>This seems counter intuitive.  I would have thought that the first expression would be faster because it can stop iterating over the list as soon as the predicate is satisfied, whereas I would have thought that the <code>.Where()</code> expression might iterate over the whole list before calling <code>.First()</code> on the resulting subset.  Even if the latter does short circuit it should not be faster than using First directly, but it is. </p>
  
  <p>Below are two really simple unit tests that illustrate this.  When compiled with optimisation on TestWhereAndFirst is about 30% faster than TestFirstOnly on .Net and Silverlight 4.  I have tried making the predicate return more results but the performance difference is the same.</p>
  
  <p>Can any one explain why <code>.First(fn)</code> is slower than <code>.Where(fn).First()</code>?  I see a similar counter intuitive result with <code>.Count(fn)</code> compared to <code>.Where(fn).Count()</code>. </p>
  
  <pre><code>private const int Range = 50000;
  
  private class Simple
  {
     public int Id { get; set; }
     public int Value { get; set; }
  }
  
  [TestMethod()]
  public void TestFirstOnly()
  {
     List&lt;Simple&gt; list = new List&lt;Simple&gt;(Range);
     for (int i = Range - 1; i &gt;= 0; --i)
     {
        list.Add(new Simple { Id = i, Value = 10 });
     }
  
     int result = 0;
     for (int i = 0; i &lt; Range; ++i)
     {
        result += list.First(f =&gt; f.Id == i).Value;
     }
  
     Assert.IsTrue(result &gt; 0);
  }
  
  [TestMethod()]
  public void TestWhereAndFirst()
  {
     List&lt;Simple&gt; list = new List&lt;Simple&gt;(Range);
     for (int i = Range - 1; i &gt;= 0; --i)
     {
        list.Add(new Simple { Id = i, Value = 10 });
     }
  
     int result = 0;
     for (int i = 0; i &lt; Range; ++i)
     {
        result += list.Where(f =&gt; f.Id == i).First().Value;
     }
  
     Assert.IsTrue(result &gt; 0);
  }
  </code></pre>