文章目录
简介
用Bjarne Stroustrup的话来说:默认情况下,当你需要一个容器时使用 Vector。
Vector 只是一个工具,像任何工具一样,它可以有效地使用,也可以无效地使用。
本文介绍 6 种优化vector使用的方法,研究使用vector执行最常见编程任务的有效和低效方法,衡量我们通过有效使用vector获得的性能增益,并尝试理解为什么我们会获得性能增益。
性能测试的实施方法
用标准库 chrono 制作一个秒表记录函数运行时间,我们将每个测试运行100次取平均运行时间进行比较。
代码放最后链接里。
注意:结果测试用 Release,别用Debug。
运行结果:

一 、通过提前保留向量的大小来避免不必要的重新分配和复制周期
程序员喜欢vector是因为可以向容器中添加项目时无需提前担心容器的大小。但是,仅从容量为 0 的vector开始并在元素进来时添加它可能会花费相当多的运行时性能,如果你提前知道你的 vector 可以有多大,那么提前保留大小是值得的。
// #1: 通过提前保留vector的大小,避免不必要的重新分配和复制周期。
vector<BigTestStruct> testVector1;
vector<BigTestStruct> testVector2;
for (int i = 0; i < 100; i++)
{
sw.Restart(); //重置时间
FillVector(testVector1); //添加一个数据结构体
tg.test1 += sw.ElapsedUs(); //微妙
sw.Restart();
//重点:用reserve先储备10000个空间
testVector2.reserve(10000);
FillVector(testVector2);
tg.test2 += sw.ElapsedUs();
testVector1.clear(); //清除内容
testVector1.shrink_to_fit(); //通过释放未使用的内存来减少内存使用
testVector2.clear();
testVector2.shrink_to_fit();
}
cout << "\n无预约填充vector的平均时间:" << (tg.test1 / 100) << endl;
cout << "有无预约填充vector的平均时间:" << (tg.test2 / 100) << endl;
在我电脑上跑,未提前保留大小用时 7027.3 微妙 , 前保留只需要 1950.07 微妙,性能提高71%

这背后的原因 Scott Meyers 在他的书 " Effective STL:50条有效使用STL的经验 " 中有解释。
对于vector 和string,每当需要更多空间时,就会执行类似于realloc的操作。这种类似realloc的操作有四个部分:
- 分配一个新的内存块,它是容器当前容量的若干倍。在大多数实现中,vector 和string 容量每次增长 1.5 到 2 倍
- 将容器旧内存中的所有元素复制到新内存中
- 销毁旧内存中的对象
- 释放旧内存
分配、回收、复制和销毁一套下来就是70%的性能。
二、使用shrink_to_fit()来释放vector ,别用clear()或erase()清除内容而不释放内存。
shrink_to_fit:通过释放未使用的内存来减少内存使用。
clear:清除内容
erase:擦除元素
通过 erase() 或 clear() 方法从向量中删除元素不会释放vector分配的内存。

不要的内存一定要用shrink_to_fit释放掉。
shrink_to_fit可能不是所有编译器都支持,可以使用swap。
container<T>( c ).swap( c )
container<T>().swap( c )
将容器中的内容与其他内容交换。不对单个元素调用任何移动、复制或交换操作。
三、当填充或复制到vector中时,最好选择 ‘=’ 赋值而不是insert()或push_back()

赋值非常有效,因为它知道它正在复制的向量的大小,并且只需要调用一次内存管理器来创建分配向量的内部缓冲区。
四、在迭代 vector 中的元素时,避免使用at() 函数
三种遍历vector的方法:
- 使用 iterator
- 使用 at()
- 使用下标 [ ]

结果:at() 函数是三种访问向量元素的方法中最慢的
五、vector别在头部插入数据

相差太多,vector的头部插入是一个 O(1) 操作。向量越大,性能越差。
6、vector插入数据时emplace_back比push_back效率高

代码
https://blog.csdn.net/a15322910600/article/details/121282425
本文介绍了提高STL vector性能的六个技巧,包括:1) 提前预留向量大小避免重新分配;2) 使用shrink_to_fit()释放内存;3) 优先选择赋值而非insert()或push_back();4) 避免在迭代时使用at()函数;5) 避免在vector头部插入数据;6) 使用emplace_back()代替push_back()。通过这些技巧,可以显著提升vector的运行效率。

8830

被折叠的 条评论
为什么被折叠?



