C++11如何减少内存拷贝次数
C++11中出现了很多迷人的特性。例如智能指针实现高效的内存管理,std::bind和std::function函数封装器,以及lambda实现的函数对象语法糖,都是使我着迷的地方。
而C++11最大的改动则是移动语义,考虑这么一个场景:将一个将亡对象A的内容拷贝给另一个对象B,然后A对象被析构释放内存,我们的程序使用B对象。这是经常发生的事情,调用函数传参或者函数返回值时最为常见。如果A和B对象占用的内存非常多,则这个操作会导致大量内存的拷贝。
为什么我们不直接将对象A的名字改成B呢?这样就省去了拷贝内存和析构的时间,增加的只是重命名的时间,在对象所占内存巨大时(例如对象是一个高度为1000的平衡二叉树(std::map),每个节点又是一个庞大的自定义结构体)。
是的,为了这个目的,C++作出了很多的努力,引用传参就能实现为对象取一个别名的作用,然而这一套别名系统必须保证原对象存在,如果原对象超出作用域被析构,则所有关于这个对象的别名都会立刻失效,这一个对象的持有者还是它自身,只是使用别名可以在对象存在期间引用它。
想要改变持有者,则可以使用智能指针,多个指针同时持有一个对象,当最后一个指针析构时会将指向的对象析构,这使得对象可以被多个指针持有,这是智能指针与引用语法的一个区别,并且智能指针是靠库实现,而引用是靠语法支持。而智能指针有一个非常大的特点,它有权力析构对象,意味着它所指向的内容必须是堆区内容,而栈上的内容则靠出栈时自动析构释放内存,如果你的大体积的对象是放在栈上,则使用智能指针是不行的。
移动语义的发明,就能解决这个问题,不管发生栈上或者堆上 大体积对象的拷贝,就可以使用移动语义,改变该对象的持有者,而不需要拷贝这块内存。还是最初 将亡值A拷贝到B的例子,依靠移动语义,拷贝时使B指向A的内容,然后A指向B的内容(也就是交换内容,注意这里的交换没有发生大内存拷贝,只是改变了指针的指向。)然后A对象释放,我们接着使用B对象,B对象的内容是A原来的内容,而A对象析构时将B对象原本要被覆盖的内容析构掉,完美。
C++从引用语法、智能指针类、移动语义多个方面支持开发者减少内存的拷贝,发挥出C++的性能威力。在设计良好的情况下,不会出现大内存块的拷贝。
C++11如何减少内存拷贝次数的更多相关文章
- emplace_back减少内存拷贝和移动
--------<深入应用C++11:代码优化与工程级应用>第2章使用C++11改进程序性能,本章将分别介绍右值引用相关的新特性.本节为大家介绍emplace_back减少内存拷贝和移动. ...
- CUDA零内存拷贝 疑问考证
今天思考了一下CUDA零内存拷贝的问题,感觉在即将设计的程序中会派上用场,于是就查了一下相关信息. 以下是一些有帮助的链接: cuda中的零拷贝用法--针对二维指针 cuda中的零拷贝用法--针对一维 ...
- python 变量作用域 v.__sizeof__() python 深复制 一切皆对象 尽量减少内存消耗
python 深入理解 赋值.引用.拷贝.作用域 - 江召伟 - 博客园 https://www.cnblogs.com/jiangzhaowei/p/5740913.html a=[1,2,5]b= ...
- 将连续增长 N 次字符串所需的内存重分配次数从必定 N 次降低为最多 N 次 二进制安全
SDS 与 C 字符串的区别 - Redis 设计与实现 http://redisbook.com/preview/sds/different_between_sds_and_c_string.htm ...
- Drawable实战解析:Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)
Android XML shape 标签使用详解 一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...
- Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)
Android XML shape 标签使用详解 一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...
- CUDA内存拷贝
原文链接1.cudaMemcpy()<--> cudaMalloc() //线性内存拷贝 1 //线性内存拷贝 2 cudaMalloc((void**)&dev_A, data ...
- C# 处理应用程序减少内存占用
SetProcessWorkingSetSize减少内存占用 系统启动起来以后,内存占用越来越大,使用析构函数.GC.Collect什么的也不见效果,后来查了好久,找到了个办法,就是使用 SetPro ...
- LeetCode-Repeated DNA Sequences (位图算法减少内存)
Repeated DNA Sequences All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, ...
随机推荐
- 模块——Getopt::Long接收客户命令行参数和Smart::Comments输出获得的命令行参数内容
我们在linux常常用到一个程序需要加入参数,现在了解一下 perl 中的有关控制参数的模块 Getopt::Long ,比直接使用 @ARGV 的数组强大多了.我想大家知道在 Linux 中有的参 ...
- Java使用Sockt进行通信(2)
使用TCP协议编写Sockt TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议,由IETF的RFC 793定义. ...
- hive新功能cube和rollup
1.cube简称数据魔方,可以实现hive多个任意维度的查询,cube(a,b,c)则首先会对(a,b,c)进行group by,然后依次是(a,b),(a,c),(a),(b,c),(b),(c), ...
- Sign Up Account In CloudAMQP
CloudAMQP 有多种账号级别,请参考下面的链接的内容访问你可以注册的级别:https://www.cloudamqp.com/plans.html 作为测试来说,你可以注册免费的的消息. 你可以 ...
- Confluence 6 安装指南
在你开始之前 在你开始安装 Confluence 之前,请确定你的安装环境满足 最小系统安装要求和支持的平台. 如果你计划将你的 Confluence 运行到虚拟环境下,请参考 Running Con ...
- Luffy之结算订单页面(订单模型表的创建,订单的生成,以及订单详情展示等)
订单页面 在前面我们已经构建了,购物车的页面,接下来到了结算页面 1.首先,在购物车页面点击去结算按钮时,我们需要做如下动作 .前端发送生成订单的请求,点击标签内触发事件 create_order t ...
- Vue 结合 Axios 接口超时统一处理
引语:当网路慢的时候.又或者公司服务器不在内地的时候,接口数据请求不回来超时报错的情况相信大家肯定遇到过的,这里我把我公司项目请求超时的处理方法分享下,希望看过后有帮助. axios基本用法就不多说了 ...
- Eclipse 手动增加linker library
多个cu文件nvcc -cubin -m64 -lcudadevrt -lcublas_device -gencode arch=compute_35,code=sm_35 -o test.cubin ...
- SQL语句中Left join,right join,inner join用法
转载于:https://blog.csdn.net/lichkui/article/details/2002895 一.先看一些最简单的例子 例子 Table Aaid adate 1 ...
- js回顾
回顾 js 组成部分 ECMAScript BOM DOM 变量声明~~ var 变量名 = 初始化值: ...