【问题标题】:How to optimize this linq to objects query?如何优化此 linq to objects 查询?
【发布时间】:2012-01-24 02:15:53
【问题描述】:

我将内存列表中的一些实体与 .contains(子选择)查询进行匹配,以从新用户中过滤掉旧用户。

检查性能问题我看到了这个:

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

【问题讨论】:

  • 1 for 12 接受的答案。可能想要改进这一点。另外,什么附加组件可以为您提供该指标?
  • 我用的是vs2010的性能分析器,自带终极版。

标签: linq linq-to-objects


【解决方案1】:

绝对 - 建立一个集合而不是每次都检查一个列表:

// 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】:

    您可以提前为您的用户 ID 创建一个HashSet&lt;T&gt;。这将导致Contains 成为 O(1) 操作:

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

    【讨论】:

      【解决方案3】:

      虽然HashSet&lt;T&gt; 的答案简单明了,但有些人可能更喜欢以 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()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多