c++ std::vector 的优化使用

vector是std命名空间的一个容器,我们可能会经常使用到,但是不适当的使用可能会使得程序很糟糕,或者说程序的性能差。

那么我们如何高效的使用vector呢?   首先我们先来分析vector内部如何实现内存动态开辟的。

问题一:   

我们往vector中存放数据的时候,如果vector的空间不够了,并且其后面的内存已经被占用,那么它就会在内存的另外一个位置,重新开辟一块足够存放数据的内存(大部分时候都是这样的),然后将以前内存中的数据拷贝到新内存,然后将新增数据也放到内存中,最后将以前的旧内存释放带掉。

从上面vector动态开辟空间的过程,我们可以看到如果空间不够,它就会重新开辟,然后将旧数据拷贝到新位置,这个拷贝数据的过程会很浪费时间,增加开销。也会导致我们使用vector的时候会很慢。(因为你数据很多,每次都将之前的数据拷贝到新位置,这很明显有很大的开销) 

解决方案:

上面说到,vector在内存不够的时候才会重新开辟空间,才会发生数据的拷贝。那如果我们一次性开辟足够的空间,这样存放数据的时候就尽可能的去避免重新开辟空间,避免发生数据的拷贝。 

所以我们需要提前指定vector开辟相应的空间。主要有两种方式:

方式一:    通过有参构造

vector<T> v1(num);

vector<T> v1(num,elem);
  
方式二:   通过reserve()函数   (推荐)

vector<T> v1;
v1.reserve(10);

使用reserve()应该注意其实预留空间而不是开辟空间。reserve注意事项

我们选择方式二,因为方式一虽然会开辟空间,但是会往内部放一个默认数据,这也会增加开销,因为我们目前只是希望开辟足够的空间来存放之后要存放的数据。


如果最后数据存放结束,有多余的空间我们可以使用shrink_to_fit()函数将多余的内存删除

问题二: 

解决了空间扩充时的消耗,但是我们往vector的内部存放数据的时候也会存在消耗。

我们以一个类对象作为例子(其余的都类似)。

v1.push_back(Student());      // 往v1中放一个Student的对象。

首先这段代码,会先创建一个Student()的对象在函数的堆栈内存上,然后将该内存的数据存放到vector管理的内存上,这就要将堆栈位置的数据拷贝到vector对应的内存。(会调用拷贝构造函数)

 会发现,如果我们存放10个对象,就会调用10次拷贝构造,这很明显也是会影响性能的。

push_back()和insert()一样

解决方案:

我们可以使用c++11提供的emplace和emplace_back()。


这两个函数接收的参数并不是我们要存储的对象,而是构建对象所用的数据。(也就是对应构造函数的参数)

其不会在函数的堆栈内存中创建对象,而是直接在vector管理的空间上使用传入的参数,调用对应的构造函数,创建对象。

这样,我们就直接在vector的内存上创建了对象,就省去了之前拷贝的过程。

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值