【发布时间】:2021-05-30 12:46:47
【问题描述】:
在新标准中引入了 std::unordered_map/std::unordered_set,它使用哈希函数,并且在我们不需要迭代集合的情况下,插入/删除/获取元素的平均复杂度恒定特别是,似乎没有理由使用“旧”std::map/std::set?或者当 std::map/std::set 是更好的选择时,还有其他一些情况/原因?就像他们是前任一样。更少的内存消耗,或者它们对“无序”版本的唯一优点是排序?
【问题讨论】:
-
FWIW,不要使用标准提供的无序容器。它们基本上需要是链表的向量。那里有更好的基于开源哈希的容器。我的建议是仅在需要维护排序顺序时使用
std::map/std::set。否则使用基于哈希的容器。 -
有序映射/集合的优点是它们是有序的。这真的是我能想到使用它们的唯一原因。
-
@NathanOliver 那里的“更好”哈希图(例如 absl )更适合许多用途,但不是全部。我尝试用我们图书馆中的那些替代品替换 unordered_set/map,在某些地方这是一个不错的收获,在一半的地方这是一个灾难性的损失。
-
@Johy 简单的答案是,当您需要性能时,每次使用时,请使用缓存友好的内容,在本例中为
unordered_map和unordered_set。但请记住,如果您将这些结构用于 buffers 并尝试从多线程上下文中访问它们,您可能会遇到麻烦,因为有时底层数组必须增长(list与vector)。本质上,在您做出最终决定之前进行基准测试和分析。 -
@NathanOliver 从我对
tessil、abseil和abseil和skarupke最流行的robin hood和hopscotch实现的经验来看,除了简单之外,它们根本无法使用类型。如果你甚至需要存储smart pointers,性能只会下降,而糟糕的hash function,其中一些会简单地放弃并崩溃或内存不足。所以我建议在决定使用std以外的任何东西之前进行基准测试。
标签: c++ algorithm c++11 hash std