条目十四《使用reserve来避免不必要的重新分配》
条目十四《使用reserve来避免不必要的重新分配》
使用vector和string的插入元素的时候,我们是不用担心内存问题的(只要不超过容器的max_size)。因为底层有分配子管理内存。在插入元素的时候,内存不够会发生像realloc的过程:
- 分配新的内存块,它有容器目前容量的几倍。在大部分实现中,vector和string的容量每次以2为因数增
长。也就是说,当容器必须扩展时,它们的容量每次翻倍。- 把所有元素从容器的旧内存拷贝到它的新内存。
- 销毁旧内存中的对象。
- 回收旧内存
先看个例子
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来避免不必要的重新分配》的更多相关文章
- 条目二十四《当效率至关重要时,请在map::operator[]与map::insert之间谨慎做出选择》
条目二十四<当效率至关重要时,请在map::operator[]与map::insert之间谨慎做出选择> 当效率至关重要时,应该在map::operator[]和map::insert之 ...
- 解剖SQLSERVER 第十四篇 Vardecimals 存储格式揭秘(译)
解剖SQLSERVER 第十四篇 Vardecimals 存储格式揭秘(译) http://improve.dk/how-are-vardecimals-stored/ 在这篇文章,我将深入研究 ...
- 只需十四步:从零开始掌握 Python 机器学习(附资源)
分享一篇来自机器之心的文章.关于机器学习的起步,讲的还是很清楚的.原文链接在:只需十四步:从零开始掌握Python机器学习(附资源) Python 可以说是现在最流行的机器学习语言,而且你也能在网上找 ...
- 条目十五《注意strng实现的多样性》
条目十五<注意strng实现的多样性> 下面以一个打印string空对象的大小切入本条目: #include #include using namespace std; int main( ...
- 只需十四步:从零开始掌握Python机器学习(附资源)
转载:只需十四步:从零开始掌握Python机器学习(附资源) Python 可以说是现在最流行的机器学习语言,而且你也能在网上找到大量的资源.你现在也在考虑从 Python 入门机器学习吗?本教程或许 ...
- Java中的集合(十四) Map的实现类LinkedHashMap
Java中的集合(十四) Map的实现类LinkedHashMap 一.LinkedHashMap的简介 LinkedHashMap是Map接口的实现类,继承了HashMap,它通过重写父类相关的方法 ...
- 我的MYSQL学习心得(十四) 备份和恢复
我的MYSQL学习心得(十四) 备份和恢复 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) ...
- 雅虎(yahoo)前端优化十四条军规
第一条.尽可能的减少 HTTP 的请求数 (Make Fewer HTTP Requests ) http请求是要开销的,想办法减少请求数自然可以提高网页速度.常用的方法,合并css,js(将一个页面 ...
- Bootstrap<基础二十四> 缩略图
Bootstrap 缩略图.大多数站点都需要在网格中布局图像.视频.文本等.Bootstrap 通过缩略图为此提供了一种简便的方式.使用 Bootstrap 创建缩略图的步骤如下: 在图像周围添加带有 ...
随机推荐
- new Com
CreateOleObject System.Win.ComObj.hpp #include <objbase.h> Winapi.ActiveX.pas CoInitiali ...
- Hadoop IO 特性详解(1)
本文结合hadoop : the definitive guide精心而作,包含作者的心血,希望可以帮助大家理解一点hdfs的皮毛,足矣.(charles@xingbod.cn) hadoop本身自带 ...
- $().each和$.each()
$().each 在dom处理上面用的较多.如果页面有多个input标签类型为checkbox,对于这时用$().each来处理多个checkbook,例如: $(“input[name=’ch’]” ...
- 解决mybatis中转义字符的问题
xml格式中不允许出现类似“>”这样的字符,有如下两种解决方法 方法一:使用转义字符 SELECT * FROM test WHERE 1 = 1 AND start_date <= CU ...
- ubuntu 编译并安装resin3.1.12+nginx1.2.6
一.先装jdk 先建立如下两个目录: mkdir /usr/lib/jvm mkdir /usr/lib/jvm/java 把jdk-6u26-linux-x64.bin文件传到上面目录下: chmo ...
- PHP 商城无限极分类
无限极分类,用的是递归,在外部调用fen()方法即可 index是刚开始寻找的顶级分类,suo是为了在前端展示的时候缩进 ,$suo=){ 一个数组用来返回的 $t=[]; 这是查询数据库的所有内容 ...
- 383. Ransom Note 在字典数组中查找笔记数组
[抄题]: Given an arbitrary ransom note string and another string containing letters from all the magaz ...
- 如何从Win7上卸载Sql 2008 R2 Express,再重装
这两天,因工作需要,需要在一台新的机器上,Win7 64位英文操作系统上,安装Sql Server 2008 R2 Express,安装的过程中出现些问题,在查找问题的过程中,考虑重装 Sql Ser ...
- sencha:日期选择组件datepicker
来源于<sencha touch权威指南> ------------------------------- 除app.js外,其它内容都与上一篇博客里的内容相同.app.js代码如下: E ...
- osm2pgsql windows “illegal option -W” error
新版本不支持 解决: 修改pg_hba.conf的METHOD为trust 参考:http://stackoverflow.com/questions/15510428/osm2pgsql-windo ...