如何优化这个linq对象查询?

时间:2012-01-23 16:37:41

标签: linq linq-to-objects

我在内存列表实体中使用.contains(subselect)查询匹配一些来过滤旧用户。

检查性能问题我看到了:

enter image description here

oldList大多有大约1000个用户,而新列表从100到500不等。有没有办法优化这个查询?

3 个答案:

答案 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()