包含容器的 STL 关联容器是否存在性能问题?

Are STL associative containers containing containers a performance issue?

在我的场景中,我有一个 std::map<std::string, std::vector<cCustomClass> >,但同样的问题也适用于 std::set。这些向量可能会变得非常大(超过 100000 个元素),所以我担心如果我向地图添加更多元素,向量是否会被重新分配或复制。

核心问题是:地图是否会在某个点复制大向量,如果是,它的成本是否与 std::vector::capacity() 成正比?

如果两者的答案都是肯定的,我有哪些选择?我的第一个解决方案是使用 std::map<std::string, std::vector<cCustomClass> * > 和(或智能指针),但我想知道这是否有必要。

我使用 C++03。如果答案取决于标准,我很感激任何关于它的评论。

Will the map copy the large vectors at some point

没有。 mapset 和其他关联容器是基于节点的。节点为每个条目独立分配,通过指针连接,当容器增长、收缩、重新平衡自身等时不需要复制或重新分配等

您对此的保证是各种容器上的迭代器失效要求。比较

  • std::map::insert

    No iterators or references are invalidated

    如果迭代器没有失效,它们指向的元素必须保留其在内存中的位置,因此插入到地图中不需要复制或移动任何现有元素。

  • std::vector::insert

    If the new size() is greater than capacity(), all iterators and references are invalidated. Otherwise, only the iterators and references before the insertion point remain valid. The past-the-end iterator is also invalidated.

    如果迭代器无效,元素可能移动、复制或移动值。特别是对于向量,元素 after 插入 必须 为 moved/copied 以使新元素 space。

    如果向量需要重新分配才能增长,所有 元素必须moved/copied 到新分配的区域。

值得注意的是,尽管 map 并没有真正影响您,现代编译器将尽可能 移动 元素。例如,您的大矢量将被移动,这比复制它便宜得多 - 如果您可以更新到 C++11 或更高版本,那就是。