【问题标题】:Speed of linq query grouping and intersect in particularlinq 查询分组的速度,特别是相交
【发布时间】:2013-09-17 22:37:14
【问题描述】:

假设存在超过 500,000 条记录的 3 个列表,我们需要执行一组操作(子集如下所示):

1) 检查列表一和列表二中的重复 ID 并检索不同的 ID,同时总结重复 ID 的“ValuesA”并将结果放入列表中。让我们将此列表称为 list12。

2) 比较列表 3 list12 之间所有具有匹配 id 的值并将结果打印到控制台。

3) 确保最佳性能。

这是我目前所拥有的:

var list1 = new List<abc>()
{ 
    new abc() { Id = 0, ValueA = 50},
    new abc() { Id = 1, ValueA = 40},
    new abc() { Id = 1, ValueA = 70}

};

var list2 = new List<abc>()
{ 
    new abc() { Id = 0, ValueA = 40},
    new abc() { Id = 1, ValueA = 60},
    new abc() { Id = 3, ValueA = 20},

};

var list3 = new List<abc>()
{ 
    new abc() { Id = 0, ValueA = 50},
    new abc() { Id = 1, ValueA = 40},
    new abc() { Id = 4, ValueA = 70},

};

1) 借助此处 [link][1] 的解决方案,我能够解决第 1 部分。

var list12 = list2.GroupBy(i => i.Id)
            .Select(g => new
            {
                Id = g.Key,
                NewValueA = g.Sum(j => j.ValueA),
            });

2) 我似乎无法从这部分正确获得完整的结果集。我可以获得匹配的帐号,也许有人知道除了哈希集之外的 faster 方式,但我还需要每个列表中的 ValueA 以及匹配的帐号。

        foreach (var values in list3.ToHashSet().Select(i => i.ID).Intersect(list12.ToHashSet().Select(j => j.UniqueAccount)))
        {
            Console.WriteLine(values)   //prints matching account number

            //?? how do I get ValueA with from both lists with this in the quickest way possible
        }

3) 我唯一尝试通过在线阅读来提高性能是使用哈希集,正如我在上面的尝试中看到的那样,但我可能做错了,有人可能有更好的解决方案

【问题讨论】:

  • 使用连接。这使您可以访问双方。
  • @usr:就是这样。谢谢

标签: c# performance linq


【解决方案1】:

我不认为任何到HashSet 的转换,无论多么有效,都会提高性能。原因是必须枚举列表以创建HashSets,然后必须枚举HashSets 以获得结果。

如果您将所有内容都放在一个 LINQ 语句中,则枚举的数量将最小化。并且通过在最后计算总和,将计算次数减少到绝对最小值:

list1.Concat(list2)
     .Join(list3, x => x.Id, l3 => l3.Id, (l12,l3) => l12)
     .GroupBy (x => x.Id)
     .Select(g => new
             {
                 Id = g.Key,
                 NewValueA = g.Sum(j => j.ValueA),
             })

您的数据显示:

    Id  NewValueA
    0   90
    1   170

我不知道我是否很好地理解了所有要求,但这应该会给你一个大致的想法。

【讨论】:

  • 您好,感谢您如此快速地回答和解释,但是您如何为 Id1 获得 170?你的意思是输入140吗?我认为您的要求降低了100%。我会检查一下并回复你。
  • 40 + 70 + 60(在 list1 和 list2 中)。
  • 你说得对,我忘了在 list1 中添加第二个值 :)。谢谢
【解决方案2】:

如果您想访问这两个元素,您可能需要加入。连接是一种非常通用的构造,可用于构造所有其他集合操作。

【讨论】:

  • 虽然您的评论引导我朝着正确的方向前进并且是正确的。我把它交给了@Gert,向我展示了如何详细了解它并更快地解决问题。还是谢谢。
猜你喜欢
  • 2014-12-25
  • 1970-01-01
  • 2011-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多