我遇到了矢量容器的问题。我正在努力提高将大量元素插入到一个向量中的性能。
基本上我正在使用vector :: reserve来扩展我的vector _children,如果需要的话:
if (_children.capacity() == _children.size())
{
_children.reserve(_children.size() * 2);
}
并使用vector :: at()在_children的末尾插入一个新元素而不是vector :: push_back():
_children.at(_children.size()) = child;
_children中已有一个元素,因此第一个元素应该插入位置1,此时的容量为2.
尽管如此,仍会抛出out_of_range错误。有人可以向我解释一下,我在这里误解了什么?即使所选位置小于矢量容量,是否也不可能只插入一个额外的元素?如果需要,我可以发布更多代码。
提前致谢。
/ MADS
答案 0 :(得分:8)
增加容量不会增加向量中的元素数量。它只是确保向量具有增长到所需大小的能力,而无需重新分配内存。即,您仍然需要致电push_back()
。
请注意,调用reserve()
以几何方式增加容量是浪费精力。 std::vector
已经这样做了。
答案 1 :(得分:1)
这会导致访问超出范围。保留内存不会影响向量的大小。
基本上,您正在手动执行push_back
内部执行的操作。为什么你认为它更有效率?
答案 2 :(得分:1)
这不是at()
的用途。 at()
是[]
的已检查版本,即访问元素。但是reserve()
不会改变元素的数量。
您应该使用reserve()
后跟push_back
或emplace_back
或insert
(最后);所有这些都是有效的,因为如果你保持在容量限制之下它们不会导致重新分配。
请注意,向量已经的行为与手动完全相同:当达到容量时,它会将分配的内存大小调整为当前大小的倍数。这是因为要求添加元素具有分摊的恒定时间复杂度。
答案 3 :(得分:0)
您必须区分容量和尺寸。您只能在大小范围内分配,而保留仅影响容量。
答案 4 :(得分:0)
vector::reserve
仅在内部保留空间,但不构造对象,并且不会更改向量的外部大小。如果您使用reserve,则需要使用push_back
。
此外,vector::at
会进行范围检查,与vector::operator[]
相比,它会慢得多。
你正在做的是试图模仿内部已经实现的部分行为向量。每当空间用完时,它的大小将扩大一定的系数(通常约为1.5或2)。如果您知道要推回许多对象并且只想要一次重新分配:
vec.reserve(vec.size() + nbElementsToAdd);
如果您没有添加足够的元素,这可能比vector
的默认行为更糟糕。
答案 5 :(得分:0)
向量的容量不是它拥有的元素数,而是它可以容纳的元素数量而不分配更多内存。容量等于或大于向量中的元素数。
在您的示例中,_children.size()
为1,但位置1没有元素。您只能使用赋值来替换现有元素,而不能添加新元素。根据定义,最后一个元素位于_children.at(_children.size()-1)
。
正确的方法是使用push_back()
,它是高度优化的,并且比插入索引更快。如果您事先知道要添加多少元素,则可以使用reserve()
作为优化。
没有必要手动调用保留,因为vector
会在必要时自动调整内部存储空间。实际上我相信你在你的例子中所做的与内部矢量的相似 - 当它达到容量时,保留当前大小的两倍。