linq查询分组和特定交叉的速度

时间:2013-09-17 11:42:00

标签: c# performance linq

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

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

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)我似乎无法从这部分正确获得完整的结果集。我可以获得匹配的帐号,也许有人知道除了hashsets之外的更快方式,但我还需要每个列表中的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)我在网上阅读中提高性能的唯一尝试就是使用我在上面尝试中看到的哈希集,但我可能做错了,有人可能有更好的解决方案

2 个答案:

答案 0 :(得分:0)

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

如果将所有内容放在一个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

我不知道我是否理解了所有要求,但这应该给你一般的想法。

答案 1 :(得分:0)

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