C# 在创建3个IEnumerables的并集时,实现O(n)性能的最简单方法是什么?
假设a、b、c都是C# 在创建3个IEnumerables的并集时,实现O(n)性能的最简单方法是什么?,c#,linq,C#,Linq,假设a、b、c都是List,我想创建它们的未排序并集。虽然性能不是非常关键,但它们可能每个都有10000个条目,所以我希望避免使用O(n^2)解决方案 AFAICT MSDN文档没有说明任何关于union的性能特征,因为不同的类型是相关的 我的直觉告诉我,如果我只做a.Union(b).Union(c),这将需要O(n^2)时间,但是新的Hashset(a).Union(b).Union(c)将是O(n) 是否有人有任何文档或指标来确认或否认此假设?您应该使用Enumerable.Union,因
List
,我想创建它们的未排序并集。虽然性能不是非常关键,但它们可能每个都有10000个条目,所以我希望避免使用O(n^2)解决方案
AFAICT MSDN文档没有说明任何关于union的性能特征,因为不同的类型是相关的
我的直觉告诉我,如果我只做a.Union(b).Union(c)
,这将需要O(n^2)时间,但是新的Hashset(a).Union(b).Union(c)
将是O(n)
是否有人有任何文档或指标来确认或否认此假设?您应该使用
Enumerable.Union
,因为它与哈希集
方法一样有效。复杂性为O(n+m),因为:
枚举此方法返回的对象时,Union
e按顺序计算第一个和第二个并生成
还没有屈服
源代码
是的,如果对多个集合使用
Enumerable.Union
,则会产生开销,因为必须为每个链接调用创建一个新集合。因此,如果您使用以下方法之一,可能会更有效(在内存消耗方面):
Concat
+Distinct
:
a.Concat(b).Concat(c)...Concat(x).Distinct()
Union
+Concat
a.Union(b.Concat(c)...Concat(x))
IEnumerable
(f.e.withint
):
新哈希集(a.Concat(b.Concat(c)…Concat(x))
前两者之间的差异可能可以忽略不计。第三种方法不是使用延迟执行,而是在内存中创建一个
HashSet
。这是一个好的、有效的方法。如果您需要此集合类型或2。如果这是查询的最终操作。但是,如果您需要对这个链式查询进行进一步的操作,您应该选择Concat+Distinct
或Union+Concat
,而@Tim Schmelter对于可枚举.Union
方法的线性时间复杂度是正确的,链接多个Union
运算符具有隐藏的开销,即每个Union
运算符在内部创建一个哈希集,该哈希集基本上与前一个运算符(加上其他项)的哈希集重复,因此与单个哈希集
方法相比,使用了更多的内存
如果我们考虑到,Union
只是Concat
+Distinct
的一个快捷方式,那么与HashSet
具有相同时间/空间复杂性的可伸缩LINQ解决方案将是:
a.Concat(b).Concat(c)...Concat(x).Distinct()
Union
为O(n)
a.Union(b).Union(c)
在大多数实现中的效率低于a.Union(b.Concat(c))
,因为它会为第一个Union操作创建一个哈希集,然后为第二个Union操作创建另一个哈希集,正如其他答案所说的那样。这两种方法最终都会产生一系列使用中的IEnumerator
对象,这会随着更多源的添加而增加成本
a.Union(b).Union(c)
在.NET Core中效率更高,因为第二个.Union()
操作将生成一个包含a
、b
和c
知识的单个对象,并将为整个操作创建一个散列集,同时避免了IEnumerator对象链。a.Union(b)。Union(c)
在内部使用哈希集(并使用更多内存)。a)除非您经常使用它,否则30000项不是那么多。b) 这里还有其他因素,比如的等于或t
的实现。c) 另一个因素:与Java不同,c#HashSet
似乎没有预先调整其内部数组大小的方法,这可能会导致HashSet
Enumerable出现更多问题
更快的是a.Union(b.Concat(c))-试试看;o) 在查看实现时,它通过set set set=new set(比较器)创建新集合
但我不确定是否使用c#中的Set
具体类型。我没有看到在Union方法中使用Hashset。因此,我对此感到困惑。@AkashKC:Set
是一个内部类,您可以找到源代码。为什么不使用HashSet
?我不知道。Afaik两者都是同时实现的,因此可能HashSet
还没有准备好使用,它们希望避免将来的冲突。然而,两者都使用相似的算法。编辑我刚刚发现这个问题:谢谢你的回答。现在,我的困惑已经消除了。在github中没有类型定义的导航功能让生活有时很艰难:(不管怎样,你的评论现在已经很清楚了。谢谢!!!
a.Concat(b).Concat(c)...Concat(x).Distinct()