【问题标题】:Linq: GroupBy vs DistinctLinq:GroupBy vs Distinct
【发布时间】:2014-02-27 10:54:42
【问题描述】:

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

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

【问题讨论】:

  • 您是否尝试过使用真实数据自己比较这两种方法的性能?
  • 从广义上讲,我希望有类似的性能,但不要让这阻止您进行自己的测量!
  • 不,实际上!我想我会这样做并回复你:)也许回答我自己的问题!谢谢大家!
  • 随便挑一个。如果您发现您的应用程序被这段特定的代码拖慢了,那么请返回并查看性能。
  • 除非您在大量查询中进行大量查询,否则我会说性能并不重要。对代码的intent 使用更正确 的那个。仅在如果您已确定实际可衡量的性能瓶颈时进行基准测试/更改/优化。

标签: c# linq


【解决方案1】:

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() 那么快。

【讨论】:

  • 我知道这是旧的,但我只是运行了一个测试(然后用谷歌搜索它并来到这个页面),我需要一个包含 100k 个项目的表中只有一列的唯一值。对于 groupby,我只是按该列分组,然后我就会得到结果。对于不同的,我首先选择该列,然后对其余部分执行不同的操作。结果:distinct 花了 37 秒。 Groupby 花了 30 秒。
  • @JonKoeter 你有链接吗?
  • @Cees 这是我在自己的电脑上运行的测试,所以没有。
  • 我刚刚运行了一个 distinct vs group by,两者都有一个 order by 子句,结果是 distinct 663ms,group by 551ms,结果与@JonKoeter 相似。这是在 VS 2017 中使用 vb.net
  • @user2728841 你运行了多少次测试?以什么顺序?测试数据的形状是什么——所有项目都相同,还是所有项目都不同?你有多少物品——十件还是一千件?我没有看到 GroupBy 应该比 Distinct 更快的情况。看到这样的案例会很有趣。
猜你喜欢
  • 1970-01-01
  • 2017-01-27
  • 1970-01-01
  • 2013-05-07
  • 1970-01-01
  • 1970-01-01
  • 2020-09-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多