title: Linq to objects: inner query performance
body: <p>During answering on one of <a href="https://stackoverflow.com/questions/46501476/using-linq-and-lambdas-to-search-dictionaryclassliststruct-data/46501492?noredirect=1#comment79958122_46501492">questions</a> I saw 2 examples of LINQ code which should work exactly same. 
  But I was wonder about performance, and found that one code much faster that another code. And I cannot understand why. </p>
  
  <p>I took datastructures from question</p>
  
  <pre><code>public struct Strc
  {
      public decimal A;
      public decimal B;
      // more stuff
  }
  
  public class CLASS
  {
      public List&lt;Strc&gt; listStrc = new List&lt;Strc&gt;();
      // other stuff
  }
  </code></pre>
  
  <p>then I wrote simple benchmark tests (used <a href="http://benchmarkdotnet.org/" rel="nofollow noreferrer">benchmarkdotnet</a> library)</p>
  
  <p><strong>UPD</strong> I included all tests which was requested</p>
  
  <pre><code>public class TestCases
  {
      private Dictionary&lt;string, CLASS&gt; dict;
  
      public TestCases()
      {
          var m = 100;
          var n = 100;
  
          dict = Enumerable.Range(0, m)
                  .Select(x =&gt; new CLASS()
                  {
                      listStrc = Enumerable.Range(0, n)
                          .Select(y =&gt; new Strc() { A = y % 4, B = y }).ToList()
                  })
                  .ToDictionary(x =&gt; Guid.NewGuid().ToString(), x =&gt; x);
      }
  </code></pre>
  
  <p>Greater than 3 tests</p>
  
  <pre><code>    [Benchmark]
      public void TestJon_Gt3()
      {
          var result = dict.Values
              .SelectMany(x =&gt; x.listStrc)
              .Where(ls =&gt; ls.A &gt; 3)
              .Select(ls =&gt; ls.B).ToArray();
      }
  
      [Benchmark]
      public void TestTym_Gt3()
      {
          var result = dict.Values
                  .SelectMany(x =&gt; x.listStrc.Where(l =&gt; l.A &gt; 3))
                  .Select(x =&gt; x.B).ToArray();
      }
  
  
      [Benchmark]
      public void TestDasblinkenlight_Gt3()
      {
          var result = dict.Values
              .SelectMany(x =&gt; x.listStrc.Select(v =&gt; v))
              .Where(l =&gt; l.A &gt; 3)
              .Select(ls =&gt; ls.B).ToArray();
      }
  
  
      [Benchmark]
      public void TestIvan_Gt3()
      {
          var result = dict.Values
              .SelectMany(x =&gt; x.listStrc.Where(l =&gt; l.A &gt; 3).Select(l =&gt; l.B))
              .ToArray();
      }
  </code></pre>
  
  <p>Return true tests</p>
  
  <pre><code>    [Benchmark]
      public void TestJon_True()
      {
          var result = dict.Values
              .SelectMany(x =&gt; x.listStrc)
              .Where(ls =&gt; true)
              .Select(ls =&gt; ls.B).ToArray();
      }
  
      [Benchmark]
      public void TestTym_True()
      {
          var result = dict.Values
                  .SelectMany(x =&gt; x.listStrc.Where(l =&gt; true))
                  .Select(x =&gt; x.B).ToArray();
      }
  
      [Benchmark]
      public void TestDasblinkenlight_True()
      {
          var result = dict.Values
              .SelectMany(x =&gt; x.listStrc.Select(v =&gt; v))
              .Where(ls =&gt; true)
              .Select(ls =&gt; ls.B).ToArray();
      }
  
  
      [Benchmark]
      public void TestIvan_True()
      {
          var result = dict.Values
              .SelectMany(x =&gt; x.listStrc.Where(l =&gt; true).Select(l =&gt; l.B))
              .ToArray();
      }
  }
  </code></pre>
  
  <p>I ran those tests </p>
  
  <pre><code>static void Main(string[] args)
  {
      var summary = BenchmarkRunner.Run&lt;TestCases&gt;();        
  }
  </code></pre>
  
  <p>and got results</p>
  
  <pre><code>// * Summary *
  
  BenchmarkDotNet=v0.10.9, OS=Windows 7 SP1 (6.1.7601)
  Processor=Intel Core i7-4770 CPU 3.40GHz (Haswell), ProcessorCount=8
  Frequency=3312841 Hz, Resolution=301.8557 ns, Timer=TSC
    [Host]     : .NET Framework 4.6.1 (CLR 4.0.30319.42000), 32bit LegacyJIT-v4.6.1076.0
    DefaultJob : .NET Framework 4.6.1 (CLR 4.0.30319.42000), 32bit LegacyJIT-v4.6.1076.0
  
  
                     Method |       Mean |      Error |     StdDev |
  ------------------------- |-----------:|-----------:|-----------:|
                TestJon_Gt3 |   655.1 us |  1.3408 us |  1.2542 us |
                TestTym_Gt3 |   353.1 us | 12.9535 us | 10.8167 us |
    TestDasblinkenlight_Gt3 |   943.9 us |  1.9563 us |  1.7342 us |
               TestIvan_Gt3 |   352.6 us |  0.7216 us |  0.6397 us |
               TestJon_True |   801.8 us |  2.7194 us |  2.2708 us |
               TestTym_True | 1,055.8 us |  3.0912 us |  2.7403 us |
   TestDasblinkenlight_True | 1,090.6 us |  2.3084 us |  2.1593 us |
              TestIvan_True |   677.7 us |  3.0427 us |  2.8461 us |
  
  // * Hints *
  Outliers
    TestCases.TestTym_Gt3: Default             -&gt; 2 outliers were removed
    TestCases.TestDasblinkenlight_Gt3: Default -&gt; 1 outlier  was  removed
    TestCases.TestIvan_Gt3: Default            -&gt; 1 outlier  was  removed
    TestCases.TestJon_True: Default            -&gt; 2 outliers were removed
    TestCases.TestTym_True: Default            -&gt; 1 outlier  was  removed
  
  // * Legends *
    Mean   : Arithmetic mean of all measurements
    Error  : Half of 99.9% confidence interval
    StdDev : Standard deviation of all measurements
    1 us   : 1 Microsecond (0.000001 sec)
  </code></pre>
  
  <p>I tried to change initial data (n and m parameters), but results was stable, TestTym was faster than TestJon each time. And TestIvan is semms fastest from all tests. I just want to understand, why it faster? Or maybe I did smthg wrong during testing? </p>