Linq:GroupBy 与 Distinct

问题描述 投票:0回答:2

我一直在尝试让 Linq 查询从集合中返回不同的值。我找到了两种方法来解决这个问题;使用 GroupBy 或 Distinct。 我知道 Distinct 是为了这项工作而设计的,但我必须在对象上实现 IEquatable。

我尝试了 GroupBy,效果很好。我想知道使用 Distinct 与 GroupBy 是否具有明显的性能优势。

c# linq
2个回答
22
投票

Distinct()
将比较集合中的整个对象(对于引用类型,您需要覆盖 GetHashCode 和 Equals)。它将枚举项目并将它们添加到集合中。简单又快速。比如:

Set<TSource> set = new Set<TSource>(comparer);

foreach (TSource tSource in source)
{
     if (!set.Add(tSource))
          continue;

     yield return tSource;
}

GroupBy()
允许您通过某个键对对象进行分组。在这种情况下,将比较键。它将需要为集合中的每个项目执行键选择器 lambda。此外,它还需要为每个不同的键创建分组,并将集合中的每个项目添加到其组中:

Func<TSource, TElement> elementSelector = x => x;

<TKey, TElement> lookup = new Lookup<TKey, TElement>(comparer);
foreach (TSource tSource in source)
{
     TKey key = keySelector(tSource);

     // simplified pseudo-code
     if (!lookup.Contains(key))
          lookup.Add(new Grouping(key)); 

     lookup[key].Add(elementSelector(tSource));
}

foreach(IGrouping<TKey, TElement> grouping in lookup)
    yield return grouping;

所以,我认为

GroupBy()
并没有那么简单
Distict()
那么快。


0
投票

老问题,但我刚才偶然发现了这个问题,并决定使用 BenchmarkDotNet 运行基准测试。 注意:问题中没有具体说明,我认为它要求的是内存中的性能。

[Benchmark]
public bool GroupBy_Count_IEnumerable()
{
    return list.GroupBy(x => x.Property).Count() > 1;
}

[Benchmark]
public bool SelectDistinct_Count_IEnumerable()
{
    return list.Select(x => x.Property).Distinct().Count() > 1;
}

结果是:

Select(x => x.Property).Distinct()
GroupBy(x => x.Property)
快。

200 件:

方法 意思是 错误 标准偏差
GroupBy_Count_IEnumerable 11.537 我们 0.4056 我们 1.1703 我们
选择Distinct_Count_IEnumerable 5.660 我们 0.0894 我们 0.0792 我们

50_000 件商品:

方法 意思是 错误 标准偏差 中位数
GroupBy_Count_IEnumerable 7.750 毫秒 0.1527 毫秒 0.2978 毫秒 7.631 毫秒
选择Distinct_Count_IEnumerable 5.352 毫秒 0.1064 毫秒 0.2747 毫秒 5.280 毫秒
© www.soinside.com 2019 - 2024. All rights reserved.