【问题标题】:resize and reserve in vector在向量中调整大小和保留
【发布时间】:2017-05-11 08:56:16
【问题描述】:

主要问题

向量的resize 是否会影响性能,即使它的容量大于它的大小?


例如,我想为伪代码编写如下代码

const size_t size_a = 2;
const size_t i_max = 3;
vector<int> a(size_a) = random_vector;
vector<int> b;

for (size_t i=0; i<i_max; i++){
    patch_a_at_the_end_of_b;
}

所以,b 每个循环都会改变它的大小,但它会单调增加,我知道b 的最终大小。


首先,我创建了一个函数concat(a,b),以便将a 修补到b 的末尾。

void concat(const vector<int> a, vector<int> &b){
    const size_t size_b = b.size();
    b.resize(size_b+a.size());
    for(size_t i=0; i<a.size(); i++)
        b[size_b + i] = a[i];
}

请注意,每次bconcat 调用时,我们都会调整向量的大小。

然后,我在主函数的for循环前面添加b.reserve

const size_t size_a = 2;
const size_t i_max = 3;
vector<int> a(size_a) = random_vector;
vector<int> b;
b.reserve(size_a*i_max);

for (size_t i=0; i<i_max; i++){
    concat(a,b);
}

【问题讨论】:

  • 问题开头一定要喊吗?
  • 我把它改成了普通字体。
  • 不应该是b.reserve(size_b + size_a * i_max);吗?
  • b = concat(a,b); concat 被定义为void。除此之外,储备机制似乎很合乎逻辑。
  • A.S.H b 首先是空的,size_b=0。我为您的第二条评论进行了编辑。

标签: c++ vector dynamic-memory-allocation


【解决方案1】:

std::vectors 操作的规范可能提供了这个问题的大部分答案。

首先将resize()指定为void resize(size_type n, value_type val = value_type()),有要求;

  • 如果 n 小于当前大小,则移除并销毁附加元素(即如果元素具有析构函数,则调用析构函数)。
  • 如果n 大于当前容器大小,则通过在末尾插入所需数量的元素来扩展内容,以达到n 的大小。如果指定了val,则将新元素初始化为val 的副本,否则进行值初始化。
  • 如果n 也大于(强调我的)大于当前容器容量,则会自动重新分配已分配的存储空间。

请注意,如果容器尺寸减小,则没有任何关于减少容器容量的说法。

现在,reserve(size_type n) 被指定为请求向量容量n 或更多元素,有要求

  • 如果 n 大于当前向量容量,函数会导致 容器重新分配其存储,将其容量增加到 n (或更高)。
  • 在所有其他情况下,函数调用不会导致重新分配并且向量容量不受影响。
  • 此函数对矢量size 没有影响,并且无法更改其元素。

这里的第二点可以理解为reserve()不能用来减容。

注意:我在上面解释,但它本质上是对resize()reserve() 标准要求的总结。

把这些点放在一起:唯一需要resize()(或任何其他增加向量大小的操作)来增加向量容量的情况是新大小超过当前容量。

除此之外,还会发生实施质量问题。但是,一种合乎逻辑的实现方式是;

  • resize()(和其他增加向量大小的操作)永远不会增加容量,除非新大小超过当前容量
  • reserve() 永远不会减少容量

在这样的实现中,在执行增加向量大小的操作之前调用 reserve() 会带来性能优势(无需实际重新分配,除非大小增长到超过使用 reserve() 指定的容量)。

如果实现使用不同的方法,情况可能会有所不同,例如在任何阶段减少容器的容量(例如,如果调用 resize() 会减少大小,它也会减少容量)。这可能是为了尽量减少容器的总内存使用量(即,只要vector 本身存在,就不会保持分配的额外容量)。如果向量的大小在大小上波动(例如,在某些情况下增加,在其他情况下减少),这会影响性能。

【讨论】:

  • 感谢您的回答!
猜你喜欢
  • 1970-01-01
  • 2012-03-20
  • 1970-01-01
  • 1970-01-01
  • 2013-08-20
  • 2021-04-09
  • 1970-01-01
  • 1970-01-01
  • 2012-11-15
相关资源
最近更新 更多