std :: unordered_set是连续的(比如std :: vector)吗?

时间:2013-01-17 17:25:33

标签: c++ performance vector c++11 unordered-set

我在std :: unordered_set中存储指针,因为我不想要任何重复(我删除了集合中的指针,所以如果有重复,我将尝试删除已经删除的指针)。我在这些集合中循环很多,因为我知道std :: vector是最快的循环容器(连续内存),我想知道std :: unordered_set是否也这样做。

如果没有,会使用std :: vector并检查指针是否被删除更快?

4 个答案:

答案 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_maplist的默认分配器不分配 连续内存中的元素。分配每个元素的内存 在插入时。

但是,您可以提供自定义分配器(例如pool allocator) 它可以从预先分配的内存池中分配元素。仍然, 数据结构中逻辑上相邻的元素可能不是物理上的 在记忆中相邻。

因此,如果循环遍历所有元素是最常用的操作,那么 unordered_map可能不是最佳解决方案。通过分析器为所有竞争解决方案运行主要用例将揭示最佳解决方案。

除此之外,unordered_map不是循环播放另一个的最佳选择 原因。请注意名称中的“无序”一词,它表达了这一点 - 与listvectormap - 不同,没有订单元素。例如,成员 函数rehash可能会更改元素的相对顺序。事实上, 只要负载系数,容器就会自动执行重新加密 在任何操作过程中都会超过max_load_factor

答案 3 :(得分:1)

std :: unordered_set应该是一个哈希映射容器,所以我们可以假设它与std :: vector相比有一点性能损失。

但是我认为如果unordered_set访问是真正的热点,你必须检查实际的分析结果。

如果您使用的STL实现是合理的,它应该为指针或int类型键提供类似于特化的向量。如果这是真的,那么专门用于指针类型的unordered_set就会像自动增长/缩小的向量一样,并且性能差异将是不明显的。