我使用.contains(subselect)查詢匹配內存列表實體中的某些實體以從新用戶中篩選出舊的實體。如何優化這個linq到對象查詢?
檢查性能問題,我看到這一點:
的oldList大多有大約在1000名他們的用戶,而新的名單,從100到500變化有沒有辦法來優化這個查詢?
我使用.contains(subselect)查詢匹配內存列表實體中的某些實體以從新用戶中篩選出舊的實體。如何優化這個linq到對象查詢?
檢查性能問題,我看到這一點:
的oldList大多有大約在1000名他們的用戶,而新的名單,從100到500變化有沒有辦法來優化這個查詢?
絕對 - 建立一個集而不是每次都檢查列表:
// 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)每個都針對整個序列(針對每個新用戶)。
您可以提前製作一個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();
雖然這些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()
1對於接受的答案爲12。可能想要改進這一點。另外,附加組件是否會爲您提供該指標? – Yuck
我使用了vs2010的性能分析器,它附帶了最終版本。 –