14. 使用reserve避免不必要的内存分配

vector、string可以自动增长来容纳更多的元素。

每当需要更多空间时,就调用与realloc类似的操作。realloc操作分为4个部分:

  1. 分配一块大小为当前容量的某个倍数的新内存。在大多数实现中,vector和string的容量每次以2的倍数增长,即每当容器需要扩张是,它们的容量即加倍。
  2. 把容器的所有元素从旧的内存中拷贝到新的内存中。
  3. 析构掉内存中的对象。
  4. 释放旧内存。

涉及到内存的分配、释放、拷贝、析构等步骤,这个过程将非常耗时。
reserve()可以使重新分配的次数降低,只有当元素个数等于当前容量时仍需插入才会重新分配。

与容量和大小相关的4个成员函数:

  • size():当前容器中有多少个元素。
  • capacity() :当前分配的内存最多可以容纳多少个元素。
  • resize(n):改变当前容器中已有元素的个数,即size() = n。如果n > size(), 使用默认构造函数构造n-size()个元素。
    如果n < size(),析构多出的size()-n个元素。函数调用之后,size() = n。
  • reserve(n):强迫容器把它的容量变为至少是n,前提是n不小于当前的大小。这通常会导致重新分配,因为容量需要增加。(如果n比当前的容量小,则vector忽略该调用,什么都不做;而string则可能把自己的容量减为size()和n中的最大值,但是string的大小肯定不变。)

当一个元素需要被插入而容器的容量不够时,就会发生重新分配过程。因此,避免重新分配的关键在于,尽早地使用reserve,把容器的容量设为足够大的值,最好是在容器刚被构造出来之后就使用reserve。

原来的代码:

std::vector<int> datas;
for (int idx = 0; idx < 1000; ++idx)
	datas.push_back(idx); 

这个操作会导致2-10次的重新分配。

修改如下:

std::vector<int> datas;
datas.reserve(1000);
for (int idx = 0; idx < 1000; ++idx)
	datas.push_back(idx); 

这个操作将不会发生重新分配,效率大幅度提升。

通常有两种方式来使用reserve以避免不必要的重新分配。
第一种方式是,若能够确定知道或大致预计容易中最终会有多少个元素,则此时可使用reserve。在这种情况下,就像上面代码中的vector一样,你可以简单地预留适当大小的空间。
第二种方式是,先预留足够大的空间,然后,当把所有数据都加入以后,再去除多余的容量。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值