包含容器的 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
没有。 map
、set
和其他关联容器是基于节点的。节点为每个条目独立分配,通过指针连接,当容器增长、收缩、重新平衡自身等时不需要复制或重新分配等
您对此的保证是各种容器上的迭代器失效要求。比较
-
No iterators or references are invalidated
如果迭代器没有失效,它们指向的元素必须保留其在内存中的位置,因此插入到地图中不需要复制或移动任何现有元素。
-
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 或更高版本,那就是。
在我的场景中,我有一个 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
没有。 map
、set
和其他关联容器是基于节点的。节点为每个条目独立分配,通过指针连接,当容器增长、收缩、重新平衡自身等时不需要复制或重新分配等
您对此的保证是各种容器上的迭代器失效要求。比较
-
No iterators or references are invalidated
如果迭代器没有失效,它们指向的元素必须保留其在内存中的位置,因此插入到地图中不需要复制或移动任何现有元素。
-
If the new
size()
is greater thancapacity()
, 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 或更高版本,那就是。