【问题标题】:Efficiency of iterators in unordered_map (C++)unordered_map (C++) 中迭代器的效率
【发布时间】:2011-01-30 18:47:10
【问题描述】:

我似乎找不到任何关于此的信息,所以我求助于 stackoverflow。 C++ 中 std::tr1::unordered_map 的迭代器效率如何?尤其是与列表迭代器相比。制作一个包装类是否有意义,该类还包含列表中的所有键以允许有效迭代(我的代码确实对 unordered_map 中的键使用了大量迭代)。对于那些会推荐 boost 的人,我不能使用它(无论出于何种原因)。

【问题讨论】:

    标签: c++ iterator unordered-map


    【解决方案1】:

    我还没有检查 TR1,但 N3035(C++0x 草案)是这样说的:

    迭代器的所有类别 只需要那些功能 可实现的给定类别 恒定时间(摊销)。所以, 迭代器的需求表 没有复杂度列。

    除了复杂性之外,该标准不会提供效率保证,因此您无法保证对 listunordered_map 进行比较,除非它们都是摊销的常数时间(即线性时间)对容器进行完整的迭代)。

    在实践中,我希望 unordered_map 迭代器至少在 list 附近,除非您的哈希图非常稀疏。在完整迭代的复杂性中可能存在 O(桶数)项。但是我从来没有看过一个专门针对 C++ 的 unordered_map 的实现,所以我不知道在简单的“链表数组”哈希表实现上会有什么装饰。如果您有一个“典型”平台对其进行测试,如果您正在尝试编写在所有 C++ 实现中绝对是最快的代码,那么运气不好,您不能;-)

    【讨论】:

      【解决方案2】:

      unordered_map 迭代器基本上只需要遍历哈希表的内部树结构。这只是意味着执行一些指针跟踪,因此应该非常有效。当然,如果您经常遍历 unordered_map,则可能一开始就使用了错误的数据结构。无论如何,这个问题的答案,就像所有性能问题一样,是让您为特定代码计时,看看它是否足够快。

      【讨论】:

      • “unordered_map 迭代器基本上只需要遍历哈希表的内部树结构。这只是意味着执行一些指针跟踪,因此应该非常有效。”不完全科学,是吗?
      • "哈希表的内部树结构" 听起来你在想一个树形图。这是一个哈希图,它不是一棵树。通常它是一个数组,其中包含许多空单元格和一些已填充单元格中的一些链表。
      • 令人震惊的是,这是最受欢迎的答案。 std::map 具有树结构。 std::unordered_map 没有。很容易看出为什么地图的迭代器在整个地图上以线性时间工作。而 unordered_map 很难做到这一点,除非它管理一个链表覆盖作为所有插入/删除操作的开销(然后通过对应于哈希表中所有元素的链表为节点提供微不足道的“下一个”操作)。
      【解决方案3】:

      不幸的是,除非您尝试过并衡量了结果,否则您无法确定某项工作是否足够有效。我可以告诉你,标准库、TR1 和 Boost 类已经引起了很多关注。对于最常见的用例,它们可能会尽可能快。遍历容器当然是一个常见的用例。

      说了这么多,你需要问自己几个问题:

      1. 表达我想要的最清晰的方式是什么?编写包装类可能会为您的代码增加不必要的复杂性。 先做对,再做快。

      2. 我能否负担额外的内存和时间来维护 listunordered_map 并行?

      3. unordered_map 真的是正确的数据结构吗?如果您最常见的用例是从头到尾遍历,那么使用vector 可能会更好,因为可以保证内存是连续的。

      【讨论】:

        【解决方案4】:

        这里的基准测试回答了https://stackoverflow.com/a/25027750/1085128 unordered_map 介于向量和映射之间以进行迭代。它比地图快得多。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-21
          • 2015-01-10
          • 2014-06-30
          相关资源
          最近更新 更多