c++ vector的reserve到底对性能影响几何?

几个属性

关于vector,有以下几个与Capacity相关的属性需要了解:

  • size: 实际大小,即实际含有几个元素
  • max_size:最大能容纳的元素个数,取决于操作系统和编译器,一般不会变化
  • resize:改变实际大小到指定值,没有设置值的位置使用默认值填充
  • capacity:容量,当前已经分配的内存能够容纳的元素个数,该值大于等于size
  • empty:是否为空,同 size == 0?,若为空则返回true,否则false
  • reserve:预先设定容量到指定值,背后执行的可能是内存分配
  • shrink_to_fit:c++11支持,缩小容量到size,该操作可能引发内存分配,但不会影响原有元素值

重点是size、resize、reserve(该调用影响的是capacity)。

可以参考下图理解size和reserve:

在这里插入图片描述

关于resize,几点说明如下:

  • c++11原型:
    • void resize (size_type n);
    • void resize (size_type n, const value_type& val);
  • 使容器的元素个数为n
  • 如果n小于当前的size,则只保留前n个元素,后面的元素被移除并析构
  • 如果n大于当前size,则容器自动扩展元素个数到n,如果指定了val,则扩展时以val填充,如果未指定,则使用值初始化
  • 如果n大于capacity,则自动扩展分配内存
  • 该方法通过插入和移除元素改变了容器内容
reserve对效率的提升

几乎所有的教程都指出,在使用vector前,要先用reserve分配内存。

因为这在已知要插入的元素个数时,可以一次性分配所有内存,而不必因为插入元素频繁执行内存分配(默认动作)。

本着一探究竟的目的,我写了个测试程序,来看一下,到底有多大的性能提升。

测试程序如下:

#include <string>
#include <chrono>

using namespace std;
using namespace std::chrono;

int main(void)
{
	vector<string> v;
	cout << "size: " << v.size() << endl;
	cout << "capacity: " << v.capacity() << endl;
	cout << "max_size: " << v.max_size() << endl;
	cout << "------------------------" << endl;

	int num = 10;
	high_resolution_clock::time_point t1 = high_resolution_clock::now();
	for (int i = 0; i < num; ++i) {
		v.push_back("abc");
	}
	high_resolution_clock::time_point t2 = high_resolution_clock::now();
	duration<double, std::milli> time_span = t2 - t1;
	cout << "1st took me " << time_span.count() << " ms" << endl;
	cout << "size: " << v.size() << endl;
	cout << "capacity: " << v.capacity() << endl;
	cout << "----------------------------------------------" << endl;

	vector<string> vc;
	cout << "size: " << vc.size() << endl;
	cout << "capacity: " << vc.capacity() << endl;
	cout << "------------------------" << endl;
	t1 = high_resolution_clock::now();
	vc.reserve(num);
	for (int i = 0; i < num; ++i) {
		v.push_back("abc");
	}
	t2 = high_resolution_clock::now();
	time_span = t2 - t1;
	cout << "2st took me " << time_span.count() << " ms" << endl;
	cout << "size: " << vc.size() << endl;
	cout << "capacity: " << vc.capacity() << endl;
	return 0;
}

程序很简单,就不多解释了,直接看结果:

size: 0
capacity: 0
max_size: 576460752303423487
------------------------
1st took me 0.003584 ms
size: 10
capacity: 16
----------------------------------------------
size: 0
capacity: 0
------------------------
2st took me 0.001318 ms
size: 0
capacity: 10

不同系统上的测试结果可能略有不同,但这也反映了一定的问题:

在测试条件下,使用reserve可比不使用效率提升3倍左右。

扩展

本测试程序只是抛出一块砖,作出一些扩展,应该能挖到更多的砖。

通过改进,可以观察测试以下场景:

  • 初始capacity为0,它的默认增长规律是怎样的,比如插入1个元素后、2个元素后
  • 插入10个元素是比较少量的,当num为10000时,一次性分配大块内存还是比较耗时的,使用reserve还会有这么大的性能提升么
  • 改变插入的元素大小和类型,是否能得到一致的结果?
  • 在不同的操作系统上测试,会有哪些不同?
  • 了解了以上内容,再撸一下vector的源代码,是不是又会有不一样的感受?
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值