vector的resize与reserve

reserve()函数为当前vector预留至少共容纳size个元素的空间.(译注:实际空间可能大于size)

resize() 函数( void resize( size_type size, TYPE val ) )改变当前vector的大小为size,且对新创建的元素赋值val


(翻译:

调整容器大小以包含count元素。

如果当前大小大于count,则容器将被缩减为其第一个count元素,就像重复调用pop_back()一样。

如果当前大小小于count,则附加元素并用值的副本初始化。)

resize和reserve函数本质都涉及了vector的内存存储空间,因为vector在内存中是连续存放的,所以当resize的空间大于现有的存储空间(capacity() 函数 返回当前vector在重新进行内存分配以前所能容纳的元素数量.)时,会重新选择更大的空间,并将所有元素复制过去。resize在初始化内存容量时有对值的初始化,所以此时push_back会产生size+1,内存容量不够,重新寻找更大的内存空间并复制所有元素,所以这个过程是很费事的。

void testResize(){
vector<int> vector1;
vector1.resize(10);
vector1.push_back(1);
vector1.push_back(2);
vector1.push_back(3);
cout<<"vector1的长度:"<<vector1.size()<<endl;//vector1的长度:13
for_each(vector1.begin(),vector1.end(),[](int x){cout<<x<<" ";});//0 0 0 0 0 0 0 0 0 0 1 2 3
cout<<endl<<"当前vector在重新进行内存分配以前所能容纳的元素数量:"<<vector1.capacity()<<endl;//20
}
void testReserve(){
vector<int> vector1;
vector1.reserve(10);
vector1.push_back(1);//vector1的长度:3
vector1.push_back(2);//1 2 3
vector1.push_back(3);
cout<<"vector1的长度:"<<vector1.size()<<endl;//vector1的长度:3
for_each(vector1.begin(),vector1.end(),[](int x){cout<<x<<" ";});// 1 2 3
cout<<endl<<"当前vector在重新进行内存分配以前所能容纳的元素数量:"<<vector1.capacity()<<endl;//10
}

插入测试

接下来探讨插入的效率的实例,分别尝试在插入大数据3.8GB和小数据380MB时,各种情况的实现。

(1)push_back直接插入

结论:费事,在插入的过程中,不断寻找“庇护所”,不断“迁移大本营”,舟车劳顿效率低下

void testPushBack_bigsize(){
vector<int> vector1;
clock_t start = clock();
for (int i = 0; i < 1000000000; ++i) {//3814MB
vector1.push_back(i);
}
cout <<"共耗时:"<< (clock() - start)/ CLOCKS_PER_SEC <<"s"<<endl;//共耗时:42s
cout <<"size:"<<vector1.size() << " capacity:" << vector1.capacity() << endl;//size:1000000000 capacity:1073741824
clock_t start2 = clock();
vector1.push_back(1);
cout <<"共耗时:"<< (clock() - start2)/ CLOCKS_PER_SEC <<"s"<<endl;//共耗时:0s
cout <<"size:"<<vector1.size() << " capacity:" << vector1.capacity() << endl;//size:1000000001 capacity:1073741824
}

(2)先reserve在push_back

结论:先分配空间再进行后续处理,能够有效的减少插入时间的损耗,耗时占原插入方式的1/3到1/2之间。

void testPushBack_byReserve_bigsize(){
vector<int> vector1;
vector1.reserve(1000000000);//3814MB
clock_t start = clock();
for (int i = 0; i < 1000000000; ++i) {
vector1.push_back(i);
}
cout <<"共耗时:"<< (clock() - start)/ CLOCKS_PER_SEC <<"s"<<endl;//共耗时:17s
cout <<"size:"<<vector1.size() << " capacity:" << vector1.capacity() << endl;//size:1000000000 capacity:1000000000
clock_t start2 = clock();
vector1.push_back(1);
cout <<"共耗时:"<< (clock() - start2)/ CLOCKS_PER_SEC <<"s"<<endl;//共耗时:76s
cout <<"size:"<<vector1.size() << " capacity:" << vector1.capacity() << endl;//size:1000000001 capacity:2000000000
}
void testPushBack_byReserve_smallsize(){
vector<int> vector1;
vector1.reserve(100000000);//381MB
clock_t start = clock();
for (int i = 0; i < 100000000; ++i) {
vector1.push_back(i);
}
cout <<"共耗时:"<< (clock() - start)/ CLOCKS_PER_SEC <<"s"<<endl;//共耗时:1s
cout <<"size:"<<vector1.size() << " capacity:" << vector1.capacity() << endl;//size:100000000 capacity:100000000
clock_t start2 = clock();
vector1.push_back(1);
cout <<"共耗时:"<< (clock() - start2)/ CLOCKS_PER_SEC <<"s"<<endl;//共耗时:2s
cout <<"size:"<<vector1.size() << " capacity:" << vector1.capacity() << endl;//size:100000001 capacity:200000000
}

(2)先resize在利用坐标进行赋值(相当于插入)

结论:在分配空间时直接对空间进行初始化,赋予初值,极大提升了存储的速率。但是在resize后进行push_back是不明智的选择。

void testinsert_byResize_bigsize(){
vector<int> vector1;
vector1.resize(1000000000);
clock_t start = clock();
for (int i = 0; i < 1000000000; ++i) {
vector1[i]=i;
}
cout <<"共耗时:"<< (clock() - start)/ CLOCKS_PER_SEC <<"s"<<endl;//共耗时:3s
cout <<"size:"<<vector1.size() << " capacity:" << vector1.capacity() << endl;//size:1000000000 capacity:1000000000
clock_t start2 = clock();
vector1.push_back(1);
cout <<"共耗时:"<< (clock() - start2)/ CLOCKS_PER_SEC <<"s"<<endl;//共耗时:66s
cout <<"size:"<<vector1.size() << " capacity:" << vector1.capacity() << endl;//size:1000000001 capacity:2000000000
}
void testinsert_byResize_smallsize(){
vector<int> vector1;
vector1.resize(100000000);
clock_t start = clock();
for (int i = 0; i < 100000000; ++i) {
vector1[i]=i;
}
cout <<"共耗时:"<< (clock() - start)/ CLOCKS_PER_SEC <<"s"<<endl;//共耗时:0s
cout <<"size:"<<vector1.size() << " capacity:" << vector1.capacity() << endl;//size:size:10000000 capacity:10000000
clock_t start2 = clock();
vector1.push_back(1);
cout <<"共耗时:"<< (clock() - start2)/ CLOCKS_PER_SEC <<"s"<<endl;//共耗时:2s
cout <<"size:"<<vector1.size() << " capacity:" << vector1.capacity() << endl;//size:10000001 capacity:20000000
}

vector优化结论

防止reallocate内存,而导致的数据拷贝产生的额外耗时

vector在push_back的时候,如果空间不足,会自动增补一些空间,如果没有预留的空间可用
就直接申请另一块可用的连续的空间,把数据拷贝过去,然后删除旧空间,使用新空间
结果造成效率低下 。

可以通过以下两种组合来防止reallocate.

  1. vector::resize() 使用array index,效率最高,但是需要提前知道size大小

  2. vector::reserve()使用 push_back(),效率一般,较原生有一定提升。

vector性能调优之resize与reserve的更多相关文章

  1. 第0/24周 SQL Server 性能调优培训引言

    大家好,这是我在博客园写的第一篇博文,之所以要开这个博客,是我对MS SQL技术学习的一个兴趣记录. 作为计算机专业毕业的人,自己对技术的掌握总是觉得很肤浅,博而不专,到现在我才发现自己的兴趣所在,于 ...

  2. JVM 性能调优实战之:一次系统性能瓶颈的寻找过程

    玩过性能优化的朋友都清楚,性能优化的关键并不在于怎么进行优化,而在于怎么找到当前系统的性能瓶颈.性能优化分为好几个层次,比如系统层次.算法层次.代码层次…JVM 的性能优化被认为是底层优化,门槛较高, ...

  3. SQL Server 性能调优培训引言

    原文:SQL Server 性能调优培训引言 大家好,这是我在博客园写的第一篇博文,之所以要开这个博客,是我对MS SQL技术学习的一个兴趣记录. 作为计算机专业毕业的人,自己对技术的掌握总是觉得很肤 ...

  4. 提高 web 应用性能之 CSS 性能调优

    简介 Web 开发中经常会遇到性能的问题,尤其是 Web 2.0 的应用.CSS 代码是控制页面显示样式与效果的最直接“工具”,但是在性能调优时他们通常被 Web 开发工程师所忽略,而事实上不规范的 ...

  5. JVM性能调优监控工具专题一:JVM自带性能调优工具(jps,jstack,jmap,jhat,jstat,hprof)

    性能分析工具jstatjmapjhatjstack 前提概要:         JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外,还有jps.jsta ...

  6. sql server 性能调优 资源等待之内存瓶颈的三种等待类型

    原文:sql server 性能调优 资源等待之内存瓶颈的三种等待类型 一.概述 这篇介绍Stolen内存相关的主要三种等待类型以及对应的waittype编号,CMEMTHREAD(0x00B9),S ...

  7. [转]提高 web 应用性能之 CSS 性能调优

    简介 Web 开发中经常会遇到性能的问题,尤其是 Web 2.0 的应用.CSS 代码是控制页面显示样式与效果的最直接“工具”,但是在性能调优时他们通常被 Web 开发工程师所忽略,而事实上不规范的 ...

  8. web前端性能调优

    最近2个月一直在做手机端和电视端开发,开发的过程遇到过各种坑.弄到快元旦了,终于把上线了.2个月干下来满满的的辛苦,没有那么忙了自己准备把前端的性能调优总结以下,以方便以后自己再次使用到的时候得于得心 ...

  9. [网站性能2]Asp.net平台下网站性能调优的实战方案

    文章来源:http://www.cnblogs.com/dingjie08/archive/2009/11/10/1599929.html 前言    最近帮朋友运营的平台进行了性能调优,效果还不错, ...

随机推荐

  1. OC静态代码检查实战

    此文已由作者杨晓授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 在Mac OS系统上,采用Xcodebuild Analyze命令和OClint工具,对iOS项目进行静态代码 ...

  2. rbenv更新ruby后rails命令无效的解决方案

    创建: 2017/11/02 更新: 2018/02/02 增加rbenv使用方法的链接     rbenv的使用: http://www.cnblogs.com/lancgg/p/8281739.h ...

  3. 洛谷 - P2181 - 对角线 - 打表 - 组合数学

    https://www.luogu.org/problemnew/show/P2181 对于某条对角线,除去从两端出发的对角线,其他的都与它有1个交点. 每个点有(n-3)条对角线,每条对角线和其余C ...

  4. Codeforces - 346A - Alice and Bob - 简单数论

    http://codeforces.com/problemset/problem/346/A 观察了一下,猜测和他们的最大公因数有关,除以最大公因数前后结果是不会变的. 那么怎么证明一定是有n轮呢?我 ...

  5. hql语法及自定义函数(含array、map讲解) + hive的java api

    本博文的主要内容如下: .hive的详细官方手册    .hive支持的数据类型   .Hive Shell .Hive工程所需依赖的jar包  .hive自定义函数 .分桶4   .附PPT hiv ...

  6. Hexo搭建博客教程(3) - 远程部署到GitHub Pages

    本章讲的是如何将本地的个人项目远程部署到 GitHub Pages,涉及到GitHub的项目仓库.Git的使用,以及Hexo的远程部署等. 1. 安装 hexo-deployer-git 插件 想要将 ...

  7. Traffic Real Time Query System HDU - 3686

    https://vjudge.net/problem/HDU-3686 点双啊,就是在求割顶的时候,另外用一个栈来存一些边 在遍历u点出发的边时,遇到树边或反向边(u,v)就把此边加入栈(可能要记一下 ...

  8. 135 Candy 分配糖果

    There are N children standing in a line. Each child is assigned a rating value.You are giving candie ...

  9. python函数基础(3)

    第1章 编码补充 1.1 字符编码对照表 1.2 编码特性 1.4 encode/decode第2章 集合 2.1 特点 2.2 [重点]作用:去重 2.3 常用操作 2.3.1 删除 2.3.2 交 ...

  10. 【C#】基础之数组排序,对象大小比较(对比器)

    C#基础之数组排序,对象大小比较 原文链接:[OutOfMemory.CN] 从个小例子开始: 1 2 3 int[] intArray = new int[]{2,3,6,1,4,5}; Array ...