2012-01-23 41 views
1

我使用.contains(subselect)查詢匹配內存列表實體中的某些實體以從新用戶中篩選出舊的實體。如何優化這個linq到對象查詢?

檢查性能問題,我看到這一點:

enter image description here

的oldList大多有大約在1000名他們的用戶,而新的名單,從100到500變化有沒有辦法來優化這個查詢?

+1

1對於接受的答案爲12。可能想要改進這一點。另外,附加組件是否會爲您提供該指標? – Yuck

+0

我使用了vs2010的性能分析器,它附帶了最終版本。 –

回答

3

絕對 - 建立一個集而不是每次都檢查列表:

// Change string to whatever the type of UserID is. 
var oldUserSet = new HashSet<string>(oldList.Select(o => o.UserID)); 
var newUsers = NewList.Where(n => !oldUserSet.Contains(n.UserID)) 
         .ToList(); 

HashSet的容納檢查應O(1)假設幾個散列衝突,而不是檢查的O(N)每個都針對整個序列(針對每個新用戶)。

2

您可以提前製作一個HashSet<T>的用戶ID。這將導致Contains成爲O(1)操作:

var oldSet = new HashSet<int>(oldList.Select(o => o.UserID)); 
var newUsers = NewList.Where(n => !oldSet.Contains(n.UserID)).ToList(); 
0

雖然這些HashSet<T>答案是簡單明瞭的,一些可能更喜歡LINQ爲中心的解決方案。

LinqToObjects使用HashSet實現join和GroupJoin。只需使用其中一個 - 此示例使用GroupJoin:

List<User> newUsers = 
    (
    from n in NewList 
    join o in oldList on n.UserId equals o.UserId into oldGroup 
    where !oldGroup.Any() 
    select n 
).ToList()