簡體   English   中英

為什么LINQ .Where(predicate).First()比.First(predicate)快?

[英]Why is LINQ .Where(predicate).First() faster than .First(predicate)?

我正在做一些性能測試,發現LINQ表達式像

result = list.First(f => f.Id == i).Property

比慢

result = list.Where(f => f.Id == i).First().Property

這似乎與直覺相反。 我以為第一個表達式會更快,因為一旦滿足謂詞,它就可以停止迭代列表,而我以為.Where()表達式可能會在調用.First()之前.Where()迭代整個列表.First() 即使后者短路,也不應比直接使用First更快。

下面是兩個非常簡單的單元測試,它們說明了這一點。 在.Net和Silverlight 4上使用TestWhereAndFirst進行優化編譯時,其速度比TestFirstOnly快30%。我試圖使謂詞返回更多結果,但是性能差異是相同的。

誰能解釋為什么.First(fn).Where(fn).First()慢? .Where(fn).Count()相比,我看到了.Count(fn)類似的反直觀結果。

private const int Range = 50000;

private class Simple
{
   public int Id { get; set; }
   public int Value { get; set; }
}

[TestMethod()]
public void TestFirstOnly()
{
   List<Simple> list = new List<Simple>(Range);
   for (int i = Range - 1; i >= 0; --i)
   {
      list.Add(new Simple { Id = i, Value = 10 });
   }

   int result = 0;
   for (int i = 0; i < Range; ++i)
   {
      result += list.First(f => f.Id == i).Value;
   }

   Assert.IsTrue(result > 0);
}

[TestMethod()]
public void TestWhereAndFirst()
{
   List<Simple> list = new List<Simple>(Range);
   for (int i = Range - 1; i >= 0; --i)
   {
      list.Add(new Simple { Id = i, Value = 10 });
   }

   int result = 0;
   for (int i = 0; i < Range; ++i)
   {
      result += list.Where(f => f.Id == i).First().Value;
   }

   Assert.IsTrue(result > 0);
}

我得到了相同的結果:where + first比first更快。

如喬恩(Jon)所述,Linq使用惰性評估,因此兩種方法的性能應該(並且應該)大致相似。

在Reflector中看,First使用一個簡單的foreach循環來遍歷集合,但是Where中有各種專門針對不同集合類型(數組,列表等)的迭代器。 大概這就是給Where帶來小的優勢的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM