【问题标题】:Most efficient C++ data structure for iterating when order doesn't matter?当顺序无关紧要时进行迭代的最有效的 C++ 数据结构?
【发布时间】:2018-07-20 07:24:35
【问题描述】:

我想保留一个对象列表,以便我可以遍历它们并通过遍历它们中的每一个来通知它们中的每一个事件。我不在乎他们收到通知的顺序,我只需要对这些对象的迭代和方法调用尽快发生。

对于此类功能,最有效的(C++ 标准库)数据结构是什么?

【问题讨论】:

  • 可能std::vector
  • 这取决于您如何迭代、您预先了解多少(例如数据结构大小)以及许多其他事情。一般来说,如果您预先知道大小,请选择 std::array 或纯 C 数组,否则选择 std::vector。如果你衡量(不要基于理论)一个问题,那么值得看看其他的:)
  • 世界上没有“最高效​​”的东西。
  • 除非每个对象在收到通知时采取的行动绝对是微不足道的,否则与处理通知所花费的时间相比,迭代所花费的时间可以忽略不计。因此,在这种情况下,根据迭代速度来选择数据结构可能是一个错误。在原始访问速度方面,很难击败普通的老式数组。

标签: c++ list data-structures


【解决方案1】:

高效迭代对cache misses 很敏感。这意味着您可以做的最好的事情(在一般情况下,不包括多线程/false cache sharing 问题)是将您的项目保持在连续的内存区域中,并按照它们的内存顺序迭代它们。连续内存由 c-array 提供,std::arraystd::vector

现在,关于调用每个项目的方法。如果您将项目存储为(任何)指针,则意味着项目本身位于 RAM 中的其他位置,可能是动态分配的,因此可能非常分散在内存中。因此,在每个项目上调用一个方法可能会涉及缓存未命中,这可能会非常昂贵。因此,值得考虑按值存储您的项目。

是的,像往常一样,不要相信我,而要相信你的分析器

【讨论】:

    【解决方案2】:

    每当您发现自己问“哪种方式更快,X 还是 Y?”或“什么是最快的 X?”之类的问题时,只有一个真正的答案:

    对其进行基准测试。

    如果您处于不确定的阶段,只能选择一个,这里是一个经验法则,除非测量结果另有规定:

    • 是固定大小吗?使用 std::array 或纯 C 数组。
    • 它是否总是在某个固定范围内?使用 std::array 或纯 C 数组。
    • 否则,请使用std::vector

    请注意,如果您在运行时找到所需的大小,则可以使用std::vector::reserve 潜在地减少所需的内存分配数量,从而提高性能。当然,你会测量它只是为了确定;)


    另请注意,“高效”可能意味着不同的东西,具体取决于您的域。例如,使用更少的 RAM 对某些人来说可能会更好,即使以 CPU 周期为代价。

    【讨论】:

      【解决方案3】:

      如果它是固定大小或具有有限的最大大小,您可以使用 C-Array。

      如果您需要动态方法,可以使用std::vectorstd::list

      我不确切知道std::vector 是如何实现的,但据我所知std::list 是作为双链表实现的,因此在 O(1) 时间内执行迭代到下一个元素,导致 O 中的总迭代(n) 时间。

      【讨论】:

        猜你喜欢
        • 2016-06-07
        • 2021-11-27
        • 2011-12-11
        • 2023-03-05
        • 1970-01-01
        • 2020-09-10
        • 1970-01-01
        • 2021-01-15
        • 1970-01-01
        相关资源
        最近更新 更多