c++ rvo vs std::move

To summarize, RVO is a compiler optimization technique, while std::move is just an rvalue cast, which also instructs the compiler that it's eligible to move the object. The price of moving is lower than copying but higher than RVO, so never apply std::move to local objects if they would otherwise be eligible for the RVO.

#include <iostream>
#include <chrono>
#include <unordered_map> class BigObject {
public:
BigObject() {
std::cout << "constructor. " << std::endl;
}
~BigObject() {
std::cout << "destructor."<< std::endl;
}
BigObject(const BigObject&) {
std::cout << "copy constructor." << std::endl;
}
BigObject(BigObject&&) {
std::cout << "move constructor"<< std::endl;
}
}; struct info
{
std::string str;
std::unordered_map <int, std::string> umap;
}; int64_t get_current_time_ns()
{
std::chrono::nanoseconds ss = std::chrono::high_resolution_clock::now().time_since_epoch();
int64_t tt = ss.count();
std::cout<<"current time:"<<tt<<std::endl;
return tt;
} std::string get_st_v1()
{
std::string st;
st = "ttppppppppppppppppppppppppppppppppppppppppppppppppppppppppp";
return st;
} std::string get_st_v2()
{
std::string st;
st = "ttppppppppppppppppppppppppppppppppppppppppppppppppppppppppp";
return std::move(st);
} info get_info_v1()
{
info ifo;
ifo.str = "ttppppppppppppppppppppppppppppppppppppppppppppppppppppppppp";
ifo.umap.insert(std::make_pair<int, std::string>(, "eggs"));
return ifo;
} info get_info_v2()
{
info ifo;
ifo.str = "ttppppppppppppppppppppppppppppppppppppppppppppppppppppppppp";
ifo.umap.insert(std::make_pair<int, std::string>(, "eggs"));
return std::move(ifo);
} BigObject foo(int n) { BigObject localObj;
return localObj;
} int main() {
auto f = foo(); int64_t t_1= get_current_time_ns(); std::cout<<"test rvo:"<<std::endl;
for(int i = ; i< ; i++)
{
std::string d1 = get_st_v1();
} int64_t t_2= get_current_time_ns(); std::cout<<"v1 time cost:"<<t_2-t_1<<std::endl; std::cout<<"test move:"<<std::endl;
for(int j = ; j< ; j++)
{
std::string d2 = get_st_v2();
}
int64_t t_3= get_current_time_ns(); std::cout<<"v2 time cost:"<<t_3-t_2<<std::endl; std::cout<<"info test rvo:"<<std::endl;
for(int m = ; m< ; m++)
{
info d3 = get_info_v1();
}
int64_t t_4= get_current_time_ns(); std::cout<<"info v1 time cost:"<<t_4-t_3<<std::endl; std::cout<<"info test move:"<<std::endl;
for(int n = ; n< ; n++)
{
info d4 = get_info_v2();
}
int64_t t_5= get_current_time_ns(); std::cout<<"info v2 time cost:"<<t_5-t_4<<std::endl; return ;
}

Result

constructor.
current time:
test rvo:
current time:
v1 time cost:
test move:
current time:
v2 time cost:
info test rvo:
current time:
info v1 time cost:
info test move:
current time:
info v2 time cost:
destructor.

Reference

https://www.ibm.com/developerworks/community/blogs/5894415f-be62-4bc0-81c5-3956e82276f3/entry/RVO_V_S_std_move?lang=en

https://stackoverflow.com/questions/17473753/c11-return-value-optimization-or-move

https://stackoverflow.com/questions/4986673/c11-rvalues-and-move-semantics-confusion-return-statement

https://stackoverflow.com/questions/12011426/how-to-use-move-semantics-with-stdstring-during-function-return

c++ rvo vs std::move的更多相关文章

  1. C++ 11 右值引用以及std::move

    转载请注明出处:http://blog.csdn.net/luotuo44/article/details/46779063 新类型: int和int&是什么?都是类型.int是整数类型,in ...

  2. Item 25: 对右值引用使用std::move,对universal引用则使用std::forward

    本文翻译自<effective modern C++>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 右值引用只能绑定那些有资格被move的对象上去.如 ...

  3. C++ 11中的右值引用以及std::move

    看了很多篇文章,现在终于搞懂了C++ 中的右值以及std::move   左值和右值最重要的区别就是右值其实是一个临时的变量 在C++ 11中,也为右值引用增加了新语法,即&&   比 ...

  4. std::move()和std::forward()

    std::move(t)负责将t的类型转换为右值引用,这种功能很有用,可以用在swap中,也可以用来解决完美转发. std::move()的源码如下 template<class _Ty> ...

  5. std::move()

    #include <iostream> #include <utility> #include <vector> #include <string> i ...

  6. C++11右值引用和std::move语句实例解析

    关键字:C++11,右值引用,rvalue,std::move,VS 2015 OS:Windows 10 右值引用(及其支持的Move语意和完美转发)是C++0x将要加入的最重大语言特性之一.从实践 ...

  7. c++ 11 移动语义、std::move 左值、右值、将亡值、纯右值、右值引用

    为什么要用移动语义 先看看下面的代码 // rvalue_reference.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #includ ...

  8. C++ 11 左值,右值,左值引用,右值引用,std::move, std::foward

    这篇文章要介绍的内容和标题一致,关于C++ 11中的这几个特性网上介绍的文章很多,看了一些之后想把几个比较关键的点总结记录一下,文章比较长.给出了很多代码示例,都是编译运行测试过的,希望能用这些帮助理 ...

  9. C++11 std::move和std::forward

    下文先从C++11引入的几个规则,如引用折叠.右值引用的特殊类型推断规则.static_cast的扩展功能说起,然后通过例子解析std::move和std::forward的推导解析过程,说明std: ...

随机推荐

  1. spring好文章整理

    彻底搞明白Spring中的自动装配和Autowired IDEA编译spring 5源码 Spring源码——IDEA读Spring源码环境搭建 导入spring源码org.springframewo ...

  2. 开源矿工工具箱新增了ETH反抽水工具

    开源矿工工具箱新增了ETH反抽水工具 —— 将决定使用Claymore挖ETH时拦截的老外的抽水归谁的权力交给矿工 众所周知,所有的挖矿辅助工具都拦截了老外的Claymore内核挖ETH时的内核开发费 ...

  3. $.ajax()方法

    1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为String类型的参数,请求方式(post或get)默认为get.注意其他http请求方法,例如 ...

  4. 解决Hangfire 导致服务器内存飙涨

    最近因为项目需要调度作业服务,之前看张队推荐过一篇https://www.cnblogs.com/yudongdong/p/10942028.html 故直接拿过来实操,发现很好用,简单.方便  执行 ...

  5. 解决Eclipe安装不上android的ADT的办法

    Eclipse,https://dl-ssl.google.com/android/eclipse/安装不上去,ADT在线安装装不了,用离线包又出问题时会不会疯掉. 显然,国内网络和谐掉了google ...

  6. new的原理及实现

    new的过程 // new运算的过程 /** * 1.创建一个空对象: * 2.该空对象的原型指向构造函数(链接原型):将构造函数的 prototype 赋值给对象的 __proto__属性: * 3 ...

  7. ES6 入门系列 (三) 尾递归

    递归我们不陌生, 那什么是尾递归呢? 为什么要用尾递归呢? 尾递归怎么用呢? 带着这三个问题我们来了解它, 我们知道递归非常耗费内存,一不小心就会发生‘栈溢出’, 相信你一定遇到过这个错误: stac ...

  8. javascript中的12种循环遍历方法1

    1:for循环 let arr = [1,2,3]; for(let i =0;i<arr.length;i++){ console.log(i,arr[i]) } //for循环是js中最常用 ...

  9. 分布式CAP定理

    根据百度百科的定义,CAP定理又称CAP原则,指的是在一个分布式系统中,Consistency(一致性). Availability(可用性).Partition tolerance(分区容错性),最 ...

  10. CentOS6.7编译安装mysql5.5(详解编译选项)

    注意!  mysql5.5之前一般都是用make编译 mysql5.5 -5.6 一般都是用cmake编译 cmake : 跨平台编译器, mysql官方提供的rpm包 mysql-client :提 ...