performance – 渐近行为IEnumerable.Intersect vs HashedSet.IntersectWith

我已经阅读了很多关于HashSet和LINQ Set Operations的帖子和博客,我得到的印象是 linq交集方法内部使用散列集作为第一个集合,IEnumerable作为第二个集合.因此,两者之间的差异是linq交集的O(n m),而两个散列集之间的散列集交集的O(n).我可以得到确认吗?在MSDN中没有记录LINQ交叉的大O.

解决方法

嗯,它是特定于实现的,所以理论上它可能会改变 – 但基本上差别只是使用HashSet.Intersect,而你是从一个哈希集开始,所以你只需要迭代一个集合.

“明显的”实现将分别给出Intersect和IntersectWith的O(M N)和O(N)复杂度 – 当然,假设一个合适的哈希码.看到任何其他实现,我会非常惊讶,我当然没有看到任何证据表明任何版本的.NET都附带了其他任何东西.

可以说,如果Intersect的两个参数都已经是HashSet< T>你可以优化它来迭代较小的集合并检查每个元素是否在较大的集合中.但是,这还有另一个问题,即集合可能不会使用相同的比较器或相交调用.

有关详细信息,请参阅我的Edulinq implementation and post,其中包括有关MSDN中不准确的说明. MSDN claims(在撰写本文时):

When the object returned by this method is enumerated,Intersect enumerates first,collecting all distinct elements of that sequence. It then enumerates second,marking those elements that occur in both sequences. Finally,the marked elements are yielded in the order in which they were collected.

无论是在排序还是时间方面,这都不是真的:

>它是最初枚举的第二个(完全是在返回序列上首次调用MoveNext()时)>结果是在它首先迭代时产生的 – 它们是流式的,而不是MSDN声称的“标记一切然后产生结果”

相关文章

目录简介使用JS互操作使用ClipLazor库创建项目使用方法简单测...
目录简介快速入门安装 NuGet 包实体类User数据库类DbFactory...
本文实现一个简单的配置类,原理比较简单,适用于一些小型项...
C#中Description特性主要用于枚举和属性,方法比较简单,记录...
[TOC] # 原理简介 本文参考[C#/WPF/WinForm/程序实现软件开机...
目录简介获取 HTML 文档解析 HTML 文档测试补充:使用 CSS 选...