简介

一直说, emplace_back 比 push_back 快, 我不信, 哈哈~~

参考链接

https://blog.csdn.net/yockie/article/details/52674366

https://www.zhihu.com/question/64493068

移动构造函数

using emplace_back avoids the extra copy or move operation required when using push_back(简单来说确实避免了移动构造函数.)

移动构造函数是C++11带来的std::move强制将左值转为右值, 简单来说就是, 你有一个指针对象, 当使用拷贝构造函数的时候, 消耗太大, 你可以只用移动构造函数, 将指针进行浅拷贝, 然后,就可以了, 这样带来性能的极大提高.

code

线上完整代码

#include <vector>
#include <string>
#include "time.hh" class Foo {
public:
Foo(std::string str) : name(str) {
std::cout << "constructor" << std::endl;
}
Foo(const Foo& f) : name(f.name) {
std::cout << "copy constructor" << std::endl;
}
Foo(Foo&& f) : name(std::move(f.name)){
std::cout << "move constructor" << std::endl;
} private:
std::string name;
};
int main() { std::vector<Foo> v;
int count = 10000000;
v.reserve(count); //预分配十万大小,排除掉分配内存的时间
const int num = 100;
{
TIME_INTERVAL_SCOPE("push_back T:");
Foo temp("ceshi645231");
for(int i=0; i<num; i++) {
v.push_back(temp);// push_back(const T&),参数是左值引用
} //打印结果:
//constructor
//copy constructor
}
std::cout << "111111111111111111111\n";
v.clear();
{
TIME_INTERVAL_SCOPE("push_back move(T):");
Foo temp("ceshi645321");
for(int i=0; i<num; i++) { v.push_back(std::move(temp));// push_back(T &&), 参数是右值引用
} //打印结果:
//constructor
//move constructor
}
std::cout << "222222222222222222222\n";
v.clear();
{
TIME_INTERVAL_SCOPE("push_back(T&&):");
for(int i=0; i<num; i++) {
v.push_back(Foo("ceshi654321"));// push_back(T &&), 参数是右值引用
} //打印结果:
//constructor
//move constructor
}
std::cout << "333333333333333333333\n";
v.clear();
{
std::string temp = "ceshi123456";
TIME_INTERVAL_SCOPE("push_back(string):");
for(int i=0; i<num; i++) {
v.push_back(temp);// push_back(T &&), 参数是右值引用
} //打印结果:
//constructor
//move constructor
}
std::cout << "444444444444444444444444444\n";
v.clear();
{
std::string temp = "ceshi123465";
TIME_INTERVAL_SCOPE("emplace_back(string):");
for(int i=0; i<num; i++) {
v.emplace_back(temp);// 只有一次构造函数,不调用拷贝构造函数,速度最快
}
//打印结果:
//constructor
}
}
#pragma once

#include <iostream>
#include <memory>
#include <string>
#ifdef GCC
#include <sys/time.h>
#else
#include <ctime>
#endif // GCC class TimeInterval
{
public:
TimeInterval(const std::string& d) : detail(d)
{
init();
} TimeInterval()
{
init();
} ~TimeInterval()
{
#ifdef GCC
gettimeofday(&end, NULL);
std::cout << detail
<< 1000 * (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / 1000
<< " ms" << endl;
#else
end = clock();
std::cout << detail
<< (double)(end - start) << " ms" << std::endl;
#endif // GCC
} protected:
void init() {
#ifdef GCC
gettimeofday(&start, NULL);
#else
start = clock();
#endif // GCC
}
private:
std::string detail;
#ifdef GCC
timeval start, end;
#else
clock_t start, end;
#endif // GCC
}; #define TIME_INTERVAL_SCOPE(d) std::shared_ptr<TimeInterval> time_interval_scope_begin = std::make_shared<TimeInterval>(d)

测试结果

constructor
copy constructor
...
copy constructor
push_back T:922 ms
111111111111111111111
constructor
move constructor
...
move constructor
push_back move(T):893 ms
222222222222222222222
constructor
move constructor
constructor
...
constructor
move constructor
constructor
move constructor
push_back(T&&):1794 ms
333333333333333333333
constructor
move constructor
...
move constructor
constructor
move constructor
push_back(string):1884 ms
444444444444444444444444444
constructor
...
constructor
emplace_back(string):933 ms

emplace_back VS push_back的更多相关文章

  1. C++11使用emplace_back代替push_back

    最近在写一段代码的时候,突然很好奇C++11中对push_back有没有什么改进以增加效率,上网搜了一些资料,发现果然新增了emplace_back方法,比push_back的效率要高很多. 首先,写 ...

  2. 学习 emplace_back() 和 push_back 的区别 emplace_back效率高

    在引入右值引用,转移构造函数,转移复制运算符之前,通常使用push_back()向容器中加入一个右值元素(临时对象)的时候,首先会调用构造函数构造这个临时对象,然后需要调用拷贝构造函数将这个临时对象放 ...

  3. 编程杂谈——使用emplace_back取代push_back

    近日在YouTube视频上看到关于vector中emplace_back与push_back区别的介绍,深感自己在现代C++中还是有不少遗漏的知识点,遂写了段代码,尝试比较两者的差别. 示例代码 #i ...

  4. emplace_back与push_back的区别

    std::vector::emplace_back     C++   Containers library   std::vector   template< class... Args &g ...

  5. C++11 vector使用emplace_back代替push_back

    C++11中,针对顺序容器(如vector.deque.list),新标准引入了三个新成员:emplace_front.emplace和emplace_back,这些操作构造而不是拷贝元素.这些操作分 ...

  6. emplace_back() 和 push_back 的区别(转)

    在引入右值引用,转移构造函数,转移复制运算符之前,通常使用push_back()向容器中加入一个右值元素(临时对象)的时候,首先会调用构造函数构造这个临时对象,然后需要调用拷贝构造函数将这个临时对象放 ...

  7. (转)C++11使用emplace_back代替push_back (其中有关于右值引用)

    最近在写一段代码的时候,突然很好奇C++11中对push_back有没有什么改进以增加效率,上网搜了一些资料,发现果然新增了emplace_back方法,比push_back的效率要高很多. 首先,写 ...

  8. C++ std::vector emplace_back 优于 push_back 的理由

    #include <iostream> #include <vector> #include <chrono> #include <windows.h> ...

  9. 【C/C++开发】emplace_back() 和 push_back 的区别

    在引入右值引用,转移构造函数,转移复制运算符之前,通常使用push_back()向容器中加入一个右值元素(临时对象)的时候,首先会调用构造函数构造这个临时对象,然后需要调用拷贝构造函数将这个临时对象放 ...

  10. emplace_back() 和 push_back 的区别

    在引入右值引用,转移构造函数,转移复制运算符之前,通常使用push_back()向容器中加入一个右值元素(临时对象)的时候,首先会调用构造函数构造这个临时对象,然后需要调用拷贝构造函数将这个临时对象放 ...

随机推荐

  1. nohup启动jar包

    1. 后台启动jar包,并追加日志到日志文件run.log nohup java -jar wash-1.0-SNAPSHOT.jar >> run.log 2>&1 &am ...

  2. Windows执行bat脚本乱码

    解决方案: 将脚本编码设置为ANSI

  3. 【深度学习】MLE视角下的VAE与DDPM损失函数推导

    正文 最大似然估计的由来 VAE和DDPM都是likelihood-based生成模型,都是通过学习分布->采样实现图像生成的: 这类模型最大的特点就是希望实现 \[\theta = \arg\ ...

  4. rider 跑不动了,快找车吧=vscode

    我的笔记本跑rdier有点吃紧了,T440s; rider的慢速是我有点难以接受了,在开发效率和性能方面综合考虑,我考虑换上vscode了. 做.net core web开发完全够用了,也不用各种等待 ...

  5. 【ROS】1.2 创建工作空间与功能包

    创建流程 创建文件夹A,A下创建文件夹src:mkdir -p A/src src下:catkin_init_workspace A下:catkin_make src下,创建工作包learning_p ...

  6. bat文件备份数据库

    @echo off/*获取当前日期*/ set "Ymd=%date:~,4%%date:~5,2%%date:~8,2%" /*数据库自带的备份脚本的存放地址 --opt -u ...

  7. 赛前十天——递归(easy)

    *理论上,递归与循环是等价的,即任何循环都可以重写为递归形式 eg: package javaPractice; public class Contest {         public stati ...

  8. idea的快捷配置2

    https://blog.csdn.net/b644ROfP20z37485O35M/article/details/84207709#t3 本文为方便自己日后再找啥的,如有不妥,还望指教 //本文只 ...

  9. WPF 的Image 控件 设置 Image.Source 的数据源,可能存在跨线程调用的问题。

    相信很多WPF 的开发,应该都很多用到 Image 这个控件来显示图片.这个图片的来源可以来自各种各样的方式获取到. 我们的组内白板.批注的扫码的功能也用到这个去生成二维码,生成后,二维码显示不出来, ...

  10. LocalSend 编译全过程深度讲解,解决手机与电脑互传文件痛点

    localsend编译 LocalSend 是一款开源.跨平台的 本地网络文件传输工具,旨在通过局域网实现设备间快速.安全的文件共享,无需依赖互联网或第三方服务器.它支持 Windows.macOS. ...