在上一节里我们讨论了通过reserve()这个成员函数去预存空间,避免“动态扩展行为”来影响效率。如果还有读者不知道这个小技巧的,可自行跳转《vector性能优化小技巧》。如果说预存reserve()是“增”,那么肯定会有“减”这个概念。在实际上工作中,当我们发现vector预存的空间太大,远远高于需求时,我们就需要“减”的这个操作,将闲置空间释放提供更多的内存。此操作我有两个方法,分别是通过swap()和shrink_to_fit()这两个成员函数。swap的意思是交换,这个词想必大家都是耳熟能详;shrink的意思是缩减,fit的意思是合适,shrink_to_fit意思就是让容器容量和容器装载匹配。前者可视为“交换指针”,采用拷贝构造的方法;后者在c++11后被引用,可视为“移花接木”,采用移动构造的方法,其效率优于前者。
接下来将通过代码的方式来详细介绍其底层和实操方式:
#include<bits/stdc++.h> /* 释放闲置空间,提高空间利用率 */ using namespace std; void test_swap() { /*原理:swap本意是交换两个同类型的vector,实质是底层三个重要指针的交换。*/ /*通过swap()进行“缩减操作 ”指的是:拷贝构造一个已知对象->交换底层指针->析构原来数据*/ cout << "通过swap()进行vector闲置空间释放\n"; vector<int> v{1,2,3,4,5}; v.reserve(10); cout << "此时容器情况:size()="<<v.size()<<" capacity()="<< v.capacity()<<'\n'; vector<int>(v).swap(v); //这里(v)指的是拷贝已有对象 cout <<"缩减后:capacity()="<< v.capacity()<< '\n'; cout << '\n'; } void test_shrink() { /*通过shrink_to_fit()进行“缩减操作 ”指的是:拷贝构造一个已知对象->进行移动构造->析构原来数据*/ cout << "通过shrink_to_fit()进行vector闲置空间释放\n"; vector<int> v{1,2,3,4,5}; v.reserve(10); cout << "此时容器情况:size()="<<v.size()<<" capacity()="<< v.capacity()<<'\n'; v.shrink_to_fit() ;//直接调用 cout <<"缩减后:capacity()="<< v.capacity()<< '\n'; cout << '\n'; } int main(){ test_swap(); test_shrink(); return 0; }
代码运行后结果:
可以看到,没有操作前容量是10,操作后容量匹配元素总和,都变成5,说明是我们成功为容器释放了闲置空间。总结:如果要进行容量“缩减”操作,笔者推荐使用shrink_to_fit(),因为它高效简洁;如果考虑到兼容性问题,就需要用到swap()了。
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程