条目十四《使用reserve来避免不必要的重新分配》

使用vector和string的插入元素的时候,我们是不用担心内存问题的(只要不超过容器的max_size)。因为底层有分配子管理内存。在插入元素的时候,内存不够会发生像realloc的过程:

  1. 分配新的内存块,它有容器目前容量的几倍。在大部分实现中,vector和string的容量每次以2为因数增

    长。也就是说,当容器必须扩展时,它们的容量每次翻倍。
  2. 把所有元素从容器的旧内存拷贝到它的新内存。
  3. 销毁旧内存中的对象。
  4. 回收旧内存

先看个例子

vector<int> vec;
for(int i = 0; i < 10; i++)
{
vec.push_back(i)
}

这个过程会发生最少4次重新分配内存的过程。再来看下一个重新分配内存涉及到哪些过程:

  • 1.new操作-->malloc
  • 2.拷贝操作
  • 3.析构对象
  • 4.释放内存

咋一看,一两次还可以接受,当插入的元素越来越多的时候,对性能的消耗是非常客观的。

上面的问题还只是其中一个问题,在插入元素时,重新分配内存会造成迭代器、指针和引用的失效。

为了优化这两个问题,在使用vector和string的时候,可以使用reserve函数。先引出四个关于容器大小和设置的成员函数:

  • size()———————获得容器的元素个数

  • capacity()———获得容器的容量

  • resize()—————强制设置容器的元素个数(参数大于当前大小,调用默认构造函数创建元素填充在尾部。小于当前大小,会析构并销毁多余的元素)

  • reserve()————强制设置容器的容量大小(参数小于现有的容量大小会忽略当前调用,大于会扩容。)

为了避免容器的不必要扩容而造成的消耗,在初始化容器的时候可以通过reserve()设置容器的容量大小,这样在插入元素的是够,只要当前的元素个数小于容量大小,都不会发生重新分配内存。这样也就不会发生迭代器、指针和引用失效等问题,也就没有多次拷贝,析构对象,释放内存的现象发生。

vector<int> vec;
vec.reserve(15);
for(int i = 0; i < 10; i++)
{
vec.push_back(i)
}

这个过程在reserve后插入元素不会发生重新分配内存过程。因为,插入的元素个数(10)小于容量的大小(15)。

可能有人说,在开始时设置过多的容量,那么不就相当于数组吗?浪费了剩余没用到内存,不用担心这个问题,我们可以等插入元素完毕的时候:

  • 调用sesize()来修剪大小
  • 使用swap()技巧。(vector tmp_vec(vec).swap(vec) 利用容器的拷贝构造不会复制空内存的原理,先创建一个纯净的临时容器,然后再交换容器内容,原来的容器就可以成为一个没有多余容量的容器,节省内存哦)

条目十四《使用reserve来避免不必要的重新分配》的更多相关文章

  1. 条目二十四《当效率至关重要时,请在map::operator[]与map::insert之间谨慎做出选择》

    条目二十四<当效率至关重要时,请在map::operator[]与map::insert之间谨慎做出选择> 当效率至关重要时,应该在map::operator[]和map::insert之 ...

  2. 解剖SQLSERVER 第十四篇 Vardecimals 存储格式揭秘(译)

    解剖SQLSERVER 第十四篇    Vardecimals 存储格式揭秘(译) http://improve.dk/how-are-vardecimals-stored/ 在这篇文章,我将深入研究 ...

  3. 只需十四步:从零开始掌握 Python 机器学习(附资源)

    分享一篇来自机器之心的文章.关于机器学习的起步,讲的还是很清楚的.原文链接在:只需十四步:从零开始掌握Python机器学习(附资源) Python 可以说是现在最流行的机器学习语言,而且你也能在网上找 ...

  4. 条目十五《注意strng实现的多样性》

    条目十五<注意strng实现的多样性> 下面以一个打印string空对象的大小切入本条目: #include #include using namespace std; int main( ...

  5. 只需十四步:从零开始掌握Python机器学习(附资源)

    转载:只需十四步:从零开始掌握Python机器学习(附资源) Python 可以说是现在最流行的机器学习语言,而且你也能在网上找到大量的资源.你现在也在考虑从 Python 入门机器学习吗?本教程或许 ...

  6. Java中的集合(十四) Map的实现类LinkedHashMap

    Java中的集合(十四) Map的实现类LinkedHashMap 一.LinkedHashMap的简介 LinkedHashMap是Map接口的实现类,继承了HashMap,它通过重写父类相关的方法 ...

  7. 我的MYSQL学习心得(十四) 备份和恢复

    我的MYSQL学习心得(十四) 备份和恢复 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) ...

  8. 雅虎(yahoo)前端优化十四条军规

    第一条.尽可能的减少 HTTP 的请求数 (Make Fewer HTTP Requests ) http请求是要开销的,想办法减少请求数自然可以提高网页速度.常用的方法,合并css,js(将一个页面 ...

  9. Bootstrap<基础二十四> 缩略图

    Bootstrap 缩略图.大多数站点都需要在网格中布局图像.视频.文本等.Bootstrap 通过缩略图为此提供了一种简便的方式.使用 Bootstrap 创建缩略图的步骤如下: 在图像周围添加带有 ...

随机推荐

  1. Spring 快速入门

    1.持久层 (1) 域模型层   (2) Dao 持久层接口  (3) DaoImpl 持久层接口实现 2.业务层 Service 业务接口层 ServiceImpl  业务接口实现 3.展现层 Sp ...

  2. webpack4+vue2+axios+vue-router的多页+单页混合应用框架

    VUE2的单页应用框架有人分享了,多页应用框架也有人分享了,这里就分享一个单页和多页的混合应用框架吧,初现雏形,还有很多需要优化和改善的地方... 结尾有github地址. 项目结构 │ ├─buil ...

  3. Java中包、类、方法、属性、常量的命名规则

    1:包(package):用于将完成不同功能的类分门别类,放在不同的目录(包)下,包的命名规则:将公司域名反转作为包名.比如www.baidu.com 对于包名:每个字母都需要小写.比如:com.ba ...

  4. mysql之数据类型以及操作数据表

    数据类型: 数据类型是指列.存储过程的参数.表达式和局部变量的数据特征,它决定了数据的存储格式,代表了不同的信息类型. ———————————————————————————————————————— ...

  5. IE6的checkbox, radio是通过defaultChecked决定是否选中

    今天五群提到的BUG,说checked没有生效,一番百度谷歌,发现是它作怪. data.handler = function() { //IE6是通过defaultChecked来实现打勾效果 ele ...

  6. POJ1308

    1.题目链接地址 http://poj.org/problem?id=1308 2.源代码 #include<iostream> using namespace std; #define ...

  7. 页面布局 frameset元素

    frameset.html: <!DOCTYPE html><html lang="en"><head> <meta charset=&q ...

  8. 算法优化》关于1D*1D的DP的优化

    关于这一主题的DP问题的优化方法,我以前写过一篇博客与其有关,是关于对递推形DP的前缀和优化,那么这种优化方法就不再赘述了. 什么叫1D*1D的DP捏,就是一共有N种状态,而每种状态都要N种决策,这就 ...

  9. 【bzoj2115】[Wc2011] Xor

    2115: [Wc2011] Xor Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 2512  Solved: 1049[Submit][Status ...

  10. 使用Maven构建多模块企业项目

    首先,前面几次学习已经学会了安装maven,如何创建maven项目等,最近的学习,终于有点进展了,搭建一下企业级多模块项目. 好了,废话不多说,具体如下: 首先新建一个maven项目,pom.xml的 ...