C# HashSet的快速交集<;int>;和列表<;int>;
我有一个C# HashSet的快速交集<;int>;和列表<;int>;,c#,algorithm,performance,intersection,hashset,C#,Algorithm,Performance,Intersection,Hashset,我有一个HashSet和一个List(HashSet大约有300万项,List大约有30万项) 我目前使用 var intersected = hashset.Intersect(list).ToArray(); 我想知道是否有更快的方法来做到这一点。可能是并行的?是的,您可以走得更快,因为您已经有了一个哈希集。LINQ使用,这实际上是每次调用时从头开始重新创建哈希集。下面是一个更快的算法: /// <summary>Yields all the elements of first
HashSet
和一个List
(HashSet大约有300万项,List大约有30万项)
我目前使用
var intersected = hashset.Intersect(list).ToArray();
我想知道是否有更快的方法来做到这一点。可能是并行的?是的,您可以走得更快,因为您已经有了一个
哈希集。LINQ使用,这实际上是每次调用时从头开始重新创建哈希集。下面是一个更快的算法:
/// <summary>Yields all the elements of first (including duplicates) that also
/// appear in second, in the order in which they appear in first.</summary>
public static IEnumerable<TSource> Intersect<TSource>(IEnumerable<TSource> first,
HashSet<TSource> second)
{
foreach (TSource element in first)
{
if (second.Contains(element)) yield return element;
}
}
我不希望它更快,如果有的话,因为工作量很大。调用lambda 300000次的开销可能会掩盖并行性的任何好处
此外,除非在查询中添加PLINQ方法,否则不会保留结果的顺序,从而进一步影响操作的性能。将大量整数存储为紧凑的位集可能比存储为哈希集
或列表
(至少如果您使用List
存储唯一整数,就像HashSet
一样)。从这个意义上讲,有几种选择:
- 内置以紧凑的方式存储每个位。例如,如果要存储从1到65000的整数,
BitArray
需要大约8125字节的内存(而如果每个位存储为8位字节,则需要65000字节)。但是,如果最高设置位非常大,BitArray
可能不会非常高效地存储内存(例如,30亿),或者如果该组位是稀疏的(存在具有设置位和/或清除位的巨大区域)。可以使用该方法将两个位数组
相交
- 压缩位集同样以紧凑的方式存储每个位,但也压缩其自身的一部分以进一步节省内存,同时仍保持集操作(如交集效率)。示例包括Elias Fano编码、咆哮位图和EWAH。请参阅比较压缩位集与未压缩位集的不同实现(
FixedBitSet
)在性能和内存方面(注意,它们比较Java实现,但在.NET情况下可能仍然有用)
HashSet
有一种方法,即使用方法IntersectWith
我们可以使用下一种方法将HashSet
和列表进行相交:
private static IEnumerable<int> Intersect(HashSet<int> hash, List<int> list)
{
HashSet<int> intersect = new HashSet<int>(list);
intersect.IntersectWith(hash);
return intersect;
}
从表中我们可以看到,最快的方法是HashSet Contains Parallel
,最慢的方法是Linq Intersect
这是用来衡量性能的数据。它们是否需要哈希集和列表?
private static IEnumerable<int> Intersect(HashSet<int> hash, List<int> list)
{
HashSet<int> intersect = new HashSet<int>(list);
intersect.IntersectWith(hash);
return intersect;
}
------------------------------------------------------------------------
| Method | Min, ms | Max, ms | Avg, ms | StdDev, ms |
------------------------------------------------------------------------
| Linq Intersect | 135 | 274 | 150 | 17 |
| HashSet Contains | 25 | 44 | 26 | 2 |
| HashSet Contains Parallel | 12 | 53 | 13 | 3 |
| HashSet IntersectWith | 57 | 89 | 61 | 4 |
------------------------------------------------------------------------