我在std :: unordered_set中存储指针,因为我不想要任何重复(我删除了集合中的指针,所以如果有重复,我将尝试删除已经删除的指针)。我在这些集合中循环很多,因为我知道std :: vector是最快的循环容器(连续内存),我想知道std :: unordered_set是否也这样做。
如果没有,会使用std :: vector并检查指针是否被删除更快?
答案 0 :(得分:15)
std::unordered_set
是否连续?
标准没有详细说明容器的确切实现...... 然而标准确实规定了许多限制实际表示的行为。
例如,std::unordered_set
需要内存稳定:即使添加/删除其他元素,对元素/地址的引用也是有效的。
实现这一目标的唯一方法是或多或少地独立分配元素。它不能通过连续的内存分配来实现,因为这样的分配必然是有限的,因此可能过度生长而不可能在更大的块中重新分配元素。
答案 1 :(得分:3)
不,它不是连续的内存,但由于哈希映射,它仍然非常快。
编辑:快速进行随机访问,如果你主要做循环,你应该考虑另一个容器。
Edit2:您应该进行分析,以便知道是否值得考虑另一个容器。 (也许你应该优化其他地方......也许)。
答案 2 :(得分:2)
std::unordered_map
提供以下成员函数的事实表明它基于散列表,也许
separate chaining with linked lists
bucket_count, hash_function, load_factor, max_load_count, rehash
元素是否连续取决于分配器。的的
unordered_map
和list
的默认分配器不分配
连续内存中的元素。分配每个元素的内存
在插入时。
但是,您可以提供自定义分配器(例如pool allocator) 它可以从预先分配的内存池中分配元素。仍然, 数据结构中逻辑上相邻的元素可能不是物理上的 在记忆中相邻。
因此,如果循环遍历所有元素是最常用的操作,那么
unordered_map
可能不是最佳解决方案。通过分析器为所有竞争解决方案运行主要用例将揭示最佳解决方案。
除此之外,unordered_map
不是循环播放另一个的最佳选择
原因。请注意名称中的“无序”一词,它表达了这一点 - 与list
,vector
或map
- 不同,没有订单元素。例如,成员
函数rehash
可能会更改元素的相对顺序。事实上,
只要负载系数,容器就会自动执行重新加密
在任何操作过程中都会超过max_load_factor
。
答案 3 :(得分:1)
std :: unordered_set应该是一个哈希映射容器,所以我们可以假设它与std :: vector相比有一点性能损失。
但是我认为如果unordered_set访问是真正的热点,你必须检查实际的分析结果。
如果您使用的STL实现是合理的,它应该为指针或int类型键提供类似于特化的向量。如果这是真的,那么专门用于指针类型的unordered_set就会像自动增长/缩小的向量一样,并且性能差异将是不明显的。