--------《深入应用C++11:代码优化与工程级应用》第2章使用C++11改进程序性能,本章将分别介绍右值引用相关的新特性。本节为大家介绍emplace_back减少内存拷贝和移动。---------

2.4 emplace_back减少内存拷贝和移动

emplace_back能就地通过参数构造对象,不需要拷贝或者移动内存,相比push_back能更好地避免内存的拷贝与移动,使容器插入元素的性能得到进一步提升。在大多数情况下应该优先使用emplace_back来代替push_back。所有的标准库容器(array除外,因为它的长度不可改变,不能插入元素)都增加了类似的方法:emplace、emplace_hint、emplace_front、emplace_after和 emplace_back,关于它们的具体用法可以参考cppreference.com。这里仅列举典型的示例。

vector的emplace_back的基本用法如下:
 

可以看出,emplace_back的用法比较简单,直接通过构造函数的参数就可以构造对象,因此,也要求对象有对应的构造函数,如果没有对应的构造函数,编译器会报错。如果把上面的构造函数注释掉,在vs2013下编译会报如下错误:
 error C2661: “A::A”: 没有重载函数接受 2 个参数

其他容器相应的emplace方法也是类似的。

相对push_back而言,emplace_back更具性能优势。下面通过一个例子来看emplace_back和push_back的性能差异,如代码清单2-5所示。

代码清单2-5 emplace_back和push_back的比较

#include <vector>
#include <map>
#include <string>
#include <iostream>
using namespace std;  struct Complicated
{  int year;  double country;  std::string name;  Complicated(int a, double b, string c):year(a),country(b),name(c)  {  cout<<"is constucted"<<endl;  }  Complicated(const Complicated&other):year(other.year),country(other.country),name(std::move(other.name))  {  cout<<"is moved"<<endl;  }
};  int main()
{  std::map<int, Complicated> m;  int anInt = 4;  double aDouble = 5.0;  std::string aString = "C++";  cout<<"—insert--"<<endl;  m.insert(std::make_pair(4, Complicated(anInt, aDouble, aString)));  cout<<"—emplace--"<<endl;  // should be easier for the optimizer  m.emplace(4, Complicated(anInt, aDouble, aString));  cout<<"--emplace_back--"<<endl;  vector<Complicated> v;  v.emplace_back(anInt, aDouble, aString);  cout<<"--push_back--"<<endl;  v.push_back(Complicated(anInt, aDouble, aString));
} 

输出如下:

代码清单2-5测试了map的emplace和vector的emplace_back,用map的insert方法插入元素时有两次内存移动,而用emplace时只有一次内存移动;用vector的push_back插入元素时有两次移动内存,而用emplace_back时没有内存移动,是直接构造的。

可以看到,emplace/emplace_back的性能比之前的insert和push_back的性能要提高很多,我们应该尽量用emplace/emplace_back来代替原来的插入元素的接口以提高性能。需要注意的是,我们还不能完全用emplace_back来取代push_back等老接口,因为在某些场景下并不能直接使用emplace来进行就地构造,比如,当结构体中没有提供相应的构造函数时就不能用emplace了,这时就只能用push_back。

另外可参考:STL vector中的emplace_back方法

转载于:https://www.cnblogs.com/carsonzhu/p/5113213.html

emplace_back减少内存拷贝和移动相关推荐

  1. C++11如何减少内存拷贝次数

    C++11中出现了很多迷人的特性.例如智能指针实现高效的内存管理,std::bind和std::function函数封装器,以及lambda实现的函数对象语法糖,都是使我着迷的地方. 而C++11最大 ...

  2. C++编码中减少内存缺陷的方法和工具

    2019独角兽企业重金招聘Python工程师标准>>> C++编码中减少内存缺陷的方法和工具 程振林,方金云,唐志敏 (中国科学院计算技术研究所,北京 100080) 摘 要:基于C ...

  3. Binder内存拷贝的本质和变迁

    说起Binder的内存拷贝,相信大多数人都听过"一次拷贝":相较于传统IPC的两次拷贝,Binder在数据传输时显得效率更高. 其实不少人在面试时都能回答出上面这句话,但若是追问他 ...

  4. memcpy()内存拷贝和赋值操作效率测试

    比较memcpy()内存拷贝和"="赋值操作效率,测试代码如下 #include <stdio.h> #include <malloc.h> #includ ...

  5. c语言内存复制函数,【C语言】 字符串操作函数及内存拷贝函数归总

    今天在这里把零散的一些常用的字符串操作函数和内存拷贝函数进行一下归总实现. 一 . 字符串操作函数 字符串操作函数有很多,这里我列举一些常用的函数,以及自实现的代码: 字符串拷贝函数: 函数原型:ch ...

  6. 使用String.intern减少内存使用

    最近写一个程序,从文件中读取一些字/词,然后存储起来供别的类引用. 对每个读入的词创建一个String,结果许多同样内容的也会存储多份,会占用大量内存. 开始的一个想法是使用map/set来存储所有遇 ...

  7. C#调用C++ memcpy实现各种参数类型的内存拷贝 VS marshal.copy的实现 效率对比

    C#调用C++ memcpy实现各种参数类型的内存拷贝 VS marshal.copy的实现 效率对比 using System; using System.Runtime.InteropServic ...

  8. 【CUDA开发】CUDA面内存拷贝用法总结

    [CUDA开发]CUDA面内存拷贝用法总结 标签(空格分隔): [CUDA开发] 主要是在调试CUDA硬解码并用D3D9或者D3D11显示的时候遇到了一些代码,如下所示: CUdeviceptr g_ ...

  9. spark减少内存消耗_将内存消耗减少20倍

    spark减少内存消耗 这将是另一个故事,与我们分享有关内存相关问题的最新经验. 该案例是从最近的客户支持案例中提取的,在该案例中,我们遇到了一个行为异常严重的应用程序,该应用程序因生产中的OutOf ...

最新文章

  1. 从零开始学python网络爬虫-从零开始学Python 三(网络爬虫)
  2. 老板和主管不懂SEO,乱给SEO人员下指令怎么办?
  3. 使用MyBatis集成阿里巴巴druid连接池(不使用spring)
  4. 如何使用Hibernate批处理DELETE语句
  5. 教你分分钟使用Retrofit+Rxjava实现网络请求
  6. asp.net 获取客户端cookie_开发中你一定碰到过的cookie和session问题,今天一并帮你解决!...
  7. HDU2109 Fighting for HDU【排序】
  8. 获取Excel数据及Sheet的方法
  9. lua劈分字符串方法及实例
  10. Linux安装JDK11
  11. Android 内外边距
  12. 新遇到的问题 , 进程退出代码是 '0xffffffff'
  13. Maven打包SpringBoot项目镜像并推送至私有Harbor仓库
  14. English Learning - Day22 作业打卡 2022.12.28 周三
  15. 如何系统学游戏建模?游戏建模必备知识
  16. Linux:未定义引用`CPU_ZERO‘
  17. 天阔服务器1620-G15如何装系统,曙光服务器和存储产品与技术介绍.pptx
  18. LeetCode 826 Most Profit Assigning Work
  19. 彻底掌握 Promise-原生Promise的实现(二) Promise的链式调用
  20. 【DOM】初识DOM

热门文章

  1. 在c语言中,什么函数能测量当前变量所占字节数,2017年9月计算机二级考试C语言预习自测题(4)...
  2. Project中将任务添加到日程表
  3. Hbuilder X mui 华为真机运行和调试 (Java本地后台接口)
  4. 怎么用python输入计算公式_python怎么把输入的数值代入公式计算
  5. MATLAB基础-matlab的搜索路径
  6. 写在最开始的话-------------我是摸鱼王
  7. APP发布“扫雷”小结
  8. 方知截教有鸿蒙,包罗万象的意思及成语解释
  9. Nikkor AS-F DX 18-200mm 镜头的国外评测译文(还没译完)
  10. 驰骋职场如何避免落入诸葛亮完美主义困局