2013-10-22 109 views
1

我有一個ArrayList ids包含String對象是ID,另一個ArrayList objs包含具有字符串ID字段的對象。現在我有一些代碼,找出其中ids沒有比賽在objs,它看起來像這樣:foreach vs LINQ找到集合之間的差異

var missing = new List<string>(); 

foreach (MyObj obj in objs) 
{ 
    if (!ids.Contains(obj.ID)) 
    { 
     missing.Add(obj.ID); 
    } 
} 

這工作得很好。但我把它改寫了這個練習,以便更好地「認爲LINQ」:

var missing = objs.Cast<MyObj>().Select(x => x.ID).Except(ids.Cast<string>()); 

I expected this LINQ to be slowerforeach + Contains方法(特別是由於Cast通話),但LINQ顯著較快運行。什麼是LINQ方法的不同做法可以帶來性能方面的好處?

+3

linq方法沒有執行,這就是爲什麼它更快。 「除外」正在使用延期執行。除此之外,它使用了一套高效的設置。 –

+0

@TimSchmelter你是什麼意思? – jltrem

+1

包含一個'missing.ToList()'並再次測量。 –

回答

5

LINQ Except使用HashSet內部,其具有O(1)Contains方法性能,當它的爲O(n),用於ArrayList。這就是爲什麼它更快。

但是,作爲蒂姆在他的評論中指出,您的Except方法並沒有真正產生任何結果。它只是定義了一個查詢。只要您需要結果,查詢就會執行。它可能會被執行多次。您應該添加ToList()調用get List<T>明確:

var missing = objs.Cast<MyObj>().Select(x => x.ID).Except(ids.Cast<string>()).ToList(); 

順便說一句,你爲什麼用ArrayList,而不是一般的List<T>

+0

ArrayList是在我工作的系統中的其他地方提供的,而不是我現在控制的東西。 – jltrem

1

Except使用HashSet<T>(或類似的東西)有效地找到哪些對象是相同的,而您的代碼使用效率較低的List<T>.Contains(或類似的方法)。