迭代HashSet最快/最安全的方法是什么
本文关键字:方法 是什么 安全 HashSet 最快 迭代 | 更新日期: 2023-09-27 18:27:16
我对C#还很陌生,但通过论坛帖子注意到在特定情况下使用HashSet
而不是List
的优势。
我目前的情况并不是我在一个List
中执行地存储了大量数据,而是我必须经常检查它的成员。
问题是,我确实也需要对其进行迭代,但它们的存储或检索顺序实际上并不重要。
我读到每个循环实际上都比下一个慢,所以我还能用最快的方法来做这件事吗?
我正在进行的.Contains()
检查的数量肯定会影响列表的性能,所以至少与HashSet
的性能进行比较会很方便。
编辑:我目前正在使用列表,在许多位置对它们进行迭代,并且在每个位置执行不同的代码。大多数情况下,当前列表包含点坐标,然后我使用这些点坐标来引用二维数组,然后根据列表的标准对其进行一些操作或其他操作。
如果我的问题没有直接的答案,那没关系,但我认为可能有其他方法可以在HashSet
上迭代,而不仅仅是foreach
循环。我目前不知道还有什么其他方法,它们提供了什么优势等。假设有其他方法,我还假设会有一种典型的首选方法,只有当它不适合需求时才会被忽略(我的需求非常基本)。
至于过早地优化,我已经知道使用列表是一个瓶颈。如何着手解决这个问题是我陷入困境的地方。甚至没有完全卡住,但我不想通过反复测试来重新发明轮子,结果发现我已经在尽我所能地做了(这是一个投资超过3个月的大型项目,列表无处不在,但肯定有一些我不想重复,有很多数据,不需要以任何特定的顺序存储,等等)。
foreach循环在索引集合(如数组)上有少量的添加开销。这主要是因为foreach比for循环多做了一点边界检查。
HashSet没有索引器,因此必须使用枚举器。
在这种情况下,foreach是高效的,因为它只在遍历集合时调用MoveNext()。
此外,Parallel.ForEach可以显著提高您的性能,这取决于您在循环中所做的工作和HashSet的大小。
如前所述,分析是您的最佳选择。
您不应该首先迭代一个哈希集来确定其中是否有项。您应该使用hashset(而不是LINQ)contains方法。HashSet的设计使得它不需要查看每个项来查看是否有任何给定的值在该集合内。这就是它在搜索列表时如此强大的原因。
不是严格回答标题中的问题,而是更多关于您的特定问题:
我会制作您自己的Collection
对象,该对象在内部同时使用HashSet
和List
。使用List可以快速迭代,使用HashSet可以快速检查Contains
。只需将其设为IEnumerable
,您也可以在foreach
中使用此集合。
缺点是内存更多,但对对象的引用只有两倍,而不是两倍。在最坏的情况下,它只有两倍的内存,但您似乎更关心性能。
添加、检查和迭代都很快。这样,由于List
,只有删除仍然是O(N)。
编辑:如果删除也需要为O(1),请使用双链接列表而不是常规列表,并将hashSet改为Dictionary<KeyType, Cell>
。您可以检查字典中的Contains,但也可以快速找到包含数据的单元格,因此从数据结构中删除很快。
我也遇到了同样的问题,其中HashSet非常适合添加唯一元素,但在for循环中获取元素时速度非常慢。我通过将HashSet转换为数组,然后在上面运行for来解决这个问题。