在向量中使用reserve()的好处 - C++

Pla*_*oks 24 c++ performance vector

在处理向量时使用reserve有什么好处.我应该什么时候使用它们?无法找到明确的答案,但我认为在使用之前提前预订会更快.

是什么说你的人比我聪明?

Mic*_*urr 28

如果您知道向量最终将保留多少元素,它将非常有用 - 它可以帮助向量避免重复分配内存(并且必须将数据移动到新内存中).

一般来说,这可能是一个你不应该担心的潜在优化,但它也没有害处(最糟糕的是,如果过度估计,你最终会浪费内存).

一个不仅仅是优化的领域是当你想确保现有的迭代器不会因添加新元素而失效时.

例如,push_back()调用可能使向量的现有迭代器无效(如果发生重新分配).但是,如果您预留了足够的元素,则可以确保不会发生重新分配.这是一种不需要经常使用的技术.

  • ...当当前可用空间用完时,重复分配/复制/移动序列会导致堆碎片. (7认同)
  • "..确保现有的迭代器不会因添加新元素而失效." 对于*特定*种类的添加都是如此(push_back示例就是这样一种).但是`insert()`将使插入点上的所有迭代器无效,即使有足够的可用容量(当然,如果容量需要调整大小,一切都会从表中删除).当然,极端版本是`insert(v.begin(),...)`,它使*all*iterators*总是*无效.值得庆幸的是,如果频繁操作一个代码,有更好的容器而不是矢量来处理它. (3认同)

Jas*_*son 7

它可能是......特别是如果你要随着时间的推移向你添加很多元素,你想要避免容器在可用插槽用完时自动进行内存扩展.

例如,反向插入(即std::vector::push_back)被认为是一个转换的 O(1)或恒定时间过程,但这是因为如果在向量的后面插入,并且向量在空间之外,它必须然后为新的元素数组重新分配内存,将旧元素复制到新数组中,然后它可以复制您尝试插入容器的元素.该过程是O(N)或线性时间复杂度,对于大矢量,可能需要相当长的时间.使用该reserve()方法允许您为向量预先分配内存,如果您知道它将至少具有某个特定大小,并且避免每次空间耗尽时重新分配内存,特别是如果您要在某些性能中进行后向插入 - 您要确保插入时间仍然是实际的O(1)复杂性过程的关键代码,并且不会导致数组的某些隐藏内存重新分配.当然,你的复制构造函数也必须是O(1)复杂度才能获得整个反向插入过程的真实O(1)复杂度,但是关于容器本身向后插入向量的实际算法如果已经预先分配了插槽的内存,则可以保持已知的复杂性.


gab*_*mdu 7

这个优秀的文章深深的解释之间的差异dequevector容器."实验2"部分显示了益处vector::reserve().


Mar*_*ork 5

如果您知道向量的最终大小,则值得使用保留。

否则,每当向量用完内部空间时,它就会重新调整缓冲区的大小。这通常涉及将内部缓冲区的大小加倍(或 1.5 * 当前大小)(如果经常这样做,可能会很昂贵)。

真正昂贵的部分是调用每个元素的复制构造函数,将其从旧缓冲区复制到新缓冲区,然后调用旧缓冲区中每个元素的析构函数。

如果复制构造函数很昂贵,那么这可能是一个问题。