条目十四《使用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 创建缩略图的步骤如下: 在图像周围添加带有 ...
随机推荐
- Oracle11gR2--删除数据库
1. 停止ORACLE数据库 [oracle@localhost oracle]$ ps -ef|grep smon oracle 72550 1 0 14:23 ? 00:00:00 ora_smo ...
- MySQL的FORMAT函数用法规则
1.FORMAT函数在mysql中是数据内容格式化的,格式化后得到结果:###,###,#####. ,); 输出结果: ,000.00 2.可以格式化数据为整数或者浮点数. ); 输出结果: 100 ...
- Android适配器Adapter的学习
Android中有很多的适配器,首先看看这些适配器的继承结构 这些适配器中,BaseAdapter用的最多,也用的最熟,先放过他,从ArrayAdapter开始 一个listAdapter用来管理一个 ...
- 正确理解Python函数是第一类对象
正确理解 Python函数,能够帮助我们更好地理解 Python 装饰器.匿名函数(lambda).函数式编程等高阶技术. 函数(Function)作为程序语言中不可或缺的一部分,太稀松平常了.但函数 ...
- 开坑数位dp
[背景] 在10月3日的dp专练中,压轴的第6题是一道数位dp,于是各种懵逼. 为了填上这个留存已久的坑,蒟蒻chty只能开坑数位dp了. [例题一][HDU2089]不要62 题目大意:给你一个区间 ...
- 13-爬取百度贴吧中的图片(python+xpath)
通过xpath分析页面,爬取页面中的图片: #_*_ coding: utf-8 _*_ ''' Created on 2018年7月15日 @author: sss function: 使用xpat ...
- Linux Valgrind命令
一.简介 C/C++程序,最常见的错误之一就是内存泄露.Valgrind 是一款 Linux下的内存调试工具,它可以对编译后的二进制程序进行内存使用监测找出内存泄漏问题. Valgrind通常包括如下 ...
- java方法学习记录
---恢复内容开始--- 方法重载:两个方法有相同的名字,但参数不同,就是方法重载,且不能仅仅依据修饰符或者返回类型的不同来重载方法. 命令行参数的使用 有时候你希望运行一个程序时候再传递给它消息.这 ...
- WEB前端--CSS
一.认识CSS 1.概念 CSS(Cascading Style Sheet,层叠样式表),可以将网页制作的更加绚丽多彩.它可以有效的对页面的布局.字体.颜色.背景和其它效果实现更加精确的控制. 2. ...
- 几种导入osm(openstreetmap)数据的方法
一osm2pgsql+postgresql+postgis osm2pgsql——是由OpenStreetMap开发的一个命令行工具负责将OSM数据导入到基于PostgresSql的Postgis的 ...