【问题标题】:Fast union of two big lists [closed]两个大列表的快速联合[关闭]
【发布时间】:2016-01-21 05:14:28
【问题描述】:

我在两个大列表(超过 100 万个条目)上使用联合,而且速度很慢(几分钟) 我需要删除重复项的功能,所以我不能使用 concat 并且我的列表没有排序。 有更快的方法吗?也许使用plinq

【问题讨论】:

  • 您需要向我们展示您的代码。两个 100 万项的列表应该能够在 Union。
  • 请注意,我的基准测试:生成 200 万个随机整数、联合并转储结果计数在 0.083 秒内运行。
  • 心理调试:您的 List 包含一个未实现 EqualsGetHashCode 的自定义结构,因此您获得了 CLR 提供的使用反射的默认(且缓慢)实现。有关实施建议,请参阅 code.logos.com/blog/2010/02/creating_equatable_objects.html

标签: c# linq union plinq


【解决方案1】:

您没有说列表中的项目是什么,但一种选择是为此任务使用适当的数据结构 - 您只想保留唯一项目 - 它是 SET 的定义,所以使用 HashSet。

var hashSet = new HashSet<int>(list1);
hashSet.UnionWith(list2);

我还测量了上面代码与 Linq.Union 的时间:

var list3 = list1.Union(list2).Distinct();

这是时间安排(HashSet.UnionWith 的工作速度几乎快了两倍):

HashSet.UnionWith
real    0m4.111s
user    0m3.890s
sys 0m0.132s

real    0m4.562s
user    0m4.074s
sys 0m0.170s

real    0m4.052s
user    0m3.851s
sys 0m0.129s

real    0m4.003s
user    0m3.814s
sys 0m0.125s

real    0m4.058s
user    0m3.858s
sys 0m0.126s


Linq.Union.Distinct
real    0m7.579s
user    0m7.014s
sys 0m0.428s

real    0m7.498s
user    0m6.965s
sys 0m0.419s

real    0m7.596s
user    0m6.994s
sys 0m0.412s

real    0m7.446s
user    0m6.917s
sys 0m0.416s

real    0m7.452s
user    0m6.928s
sys 0m0.403s

【讨论】:

  • 我相信Union在内部使用了Set,所以性能应该差不多
  • @Rob 它实际上使用了内部 Set 类而不是 HashSet (github.com/dotnet/corefx/blob/master/src/System.Linq/src/System/…) 不确定它们对于add 操作是否具有相同的性能,让我检查一下。
  • @Rob for me UnionWith 在 Mono 上的工作速度比 Linq.Union 快 20-25%。
猜你喜欢
  • 2017-12-12
  • 1970-01-01
  • 1970-01-01
  • 2010-12-06
  • 2014-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多