2010-07-16 41 views
9

Linq做了很多聰明的事情,例如在IList上使用Count()方法返回Count屬性的結果。 有沒有一個很好的資源來概述這種優化?有沒有一個很好的資源來概述linq優化?

這將是非常有趣的,因爲作爲之前,我知道上面的,我從來沒有使用過Count(),因此經常返回List<T>不僅僅是一個IEnumerable<T>因爲我知道來電者將需要經常需要在列表的實例數。

但記住Count()並不真正包含在IEnumerable<T>中包含的實例,而是返回來自返回List的Count屬性的結果,因此不會丟失性能,導致我改變了很多返回的類型從列表到IEnumerable<T>

+0

什麼「Linq做了很多優化,例如使用IList上的Count()方法返回Count屬性的結果」意味着什麼? – 2010-07-16 10:45:24

+0

@Mitch:假設一個簡單的Count()調用會執行,LINQ查詢不會檢索所有的底層數據。 – 2010-07-16 10:47:10

+0

幾分鐘前,我學到了在列表上調用AsEnumerable不會創建新實例,而只是返回實例本身。但是,也許優化這個詞不是正確的。 A已經改變了問題文本以更準確地表達我的意思。 – HCL 2010-07-16 10:48:20

回答

6

,我所知道的目前的優化:

的優化,可能是有,但不是:

  • Last/LastOrDefault不要在使用謂詞的情況下優化。沒有理由爲什麼他們不能優化IList<T>,向後遍歷列表並通過索引訪問每個元素。

  • SequenceEqual可以優化ICollection<T>ICollection,使用Count屬性來確定名單的長度相同,早期打破瞭如果他們不。

  • Skip可以優化爲IList<T>,通過索引訪問的元素和直接在索引Ñ開始而不是迭代並丟棄所述第一Ñ元件。

  • ToArray/ToList也可以優化ICollection,使用Count屬性來更有效地分配存儲器。

  • ToDictionary可以優化爲ICollection<T>ICollection,使用Count屬性來更efficently分配內存。

+1

我在開發[Nito.Linq](http://nitolinq.codeplex.com/)庫的同時使用了Reflector深入研究了這個問題。盧克的回答非常完整。我只會補充說'ToList'和'ToArray'確實使用'Count'來減少內存重新分配。另外,'Empty'和'SequenceEqual'可以通過使用'Count'進行優化。最後,還有一個優化'Reverse'的潛力,但它有爭議,因爲它改變了語義[從緩衝到流式傳輸](http://msmvps.com/blogs/jon_skeet/archive/2010/03/25/just-how -lazy-是-you.aspx)。 – 2010-07-16 13:21:17

+0

@Stephen:我忘了所有關於'SequenceEqual'可能的優化,儘管我在我自己的LINQ輔助函數庫中有一個優化版本。我會將它添加到列表中。你能否詳細說明'Empty'可能會如何優化?據我所知,它只是返回一個單獨的空序列。 – LukeH 2010-07-16 13:47:52

+0

你是對的;我仔細檢查了我的筆記,錯誤地將「Empty」放入了我的評論。抱歉... – 2010-07-16 13:48:41

13

嘗試.NET Reflector。這是一個瀏覽類庫的好工具,它有一個強大的反編譯器,可以讓你在寫代碼的時候查看源代碼。

例如該Count()擴展方法來實現這樣的

if (source == null) 
{ 
    throw Error.ArgumentNull("source"); 
} 
ICollection<TSource> is2 = source as ICollection<TSource>; 
if (is2 != null) 
{ 
    return is2.Count; 
} 
ICollection is3 = source as ICollection; 
if (is3 != null) 
{ 
    return is3.Count; 
} 
int num = 0; 
using (IEnumerator<TSource> enumerator = source.GetEnumerator()) 
{ 
    while (enumerator.MoveNext()) 
    { 
     num++; 
    } 
} 
return num; 

在起飛的機會,源沒有實現Collection接口,你必須指望獲得實際的帳戶相關聯。以這種方式瀏覽代碼是學習的好方法。

相關問題