我在内存列表实体中使用.contains(subselect)查询匹配一些来过滤旧用户。
检查性能问题我看到了:
oldList大多有大约1000个用户,而新列表从100到500不等。有没有办法优化这个查询?
答案 0 :(得分: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)。
答案 1 :(得分: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();
答案 2 :(得分: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()