c++ rvo vs std::move

2023-05-16

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>(6, "eggs"));
    return ifo;
}

info get_info_v2()
{
    info ifo;
    ifo.str = "ttppppppppppppppppppppppppppppppppppppppppppppppppppppppppp";
    ifo.umap.insert(std::make_pair<int, std::string>(6, "eggs"));
    return std::move(ifo);
}

BigObject foo(int n) {

    BigObject localObj;
    return localObj;
}

int main() {
    auto f = foo(1);

    int64_t t_1= get_current_time_ns();

    std::cout<<"test rvo:"<<std::endl;
    for(int i = 0; i< 100000; 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 = 0; j< 100000; 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 = 0; m< 100000; 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 = 0; n< 100000; 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 0;
}  

 

Result


constructor. 
current time:1568273863513694551
test rvo:
current time:1568273863517139874
v1 time cost:3445323
test move:
current time:1568273863521213442
v2 time cost:4073568
info test rvo:
current time:1568273863574775754
info v1 time cost:53562312
info test move:
current time:1568273863641223923
info v2 time cost:66448169
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

转载于:https://www.cnblogs.com/pugang/p/11512501.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 特定于平台的 std::chrono::high_resolution_clock::period::num

    我注意到了std chrono high resolution clock period num 1对于我测试过的每个系统 是否存在任何系统 嵌入式 桌面 移动或其他 它恰好是其他数字 在这样的系统上 1 秒不能用刻度来表示 有以下三种实现
  • Visual C++ 2010 在调试时拒绝显示 std::string 值。显示<错误指针>

    我有一种奇怪的感觉 就像这是最近出现的问题 并且发生在两台不同的计算机上 当我调试并尝试查看 STL 中的 std string 的值时 它显示为值 它说它的大小是15 容量是一些乱码的巨大数字 数组值本身都显示 CXX0030 错误 无法
  • git,在保留历史记录的同时移动/重命名文件的可靠方法

    我知道有 很多 现有问题看起来很相似 所以让我在问我的问题之前总结一下它们 答案是是否可以在 git 中移动 重命名文件并保留其历史记录 https stackoverflow com questions 2314652 is it pos
  • Android ndk std::to_string 支持

    我正在使用 android NDK r9d 和工具链 4 8 但我无法使用 std to string 函数 编译器会抛出此错误 error to string is not a member of std android ndk不支持这个
  • 我们可以依靠减少容量的技巧吗?

    它真的能保证以下减少容量的技巧在任何地方都能 起作用 吗 int main std string s lololololol s capacity still non zero string s swap s 它似乎对我来说 不起作用 因为
  • 根据插入时间从 std::map 中删除元素

    我需要根据插入时间 或其他比这更有效的方法 从 std map 中删除元素 该地图可能会包含数千个元素 如果我存储时间并迭代地图以检查每个元素的时间 那么最终可能会非常耗时 有谁知道如何在 std map 变老时删除它们 The std m
  • C++ TR2 文件系统库的状态如何?

    截至上次布里斯托尔会议 C TR2 文件系统库的状态如何 它将成为 C 1Y C 14 的一部分 还是暂停 或者最近三次会议有任何已知的评论吗 It has 最近获得ISO委员会一致批准 http article gmane org gma
  • STL容器的范围插入函数在c ++ 11下返回void?

    刚刚学习c 所以我可能没有正确理解这一点 但我只读到范围插入函数在新标准下返回一个迭代器 C Primer 5th Ed cplusplus com http www cplusplus com reference string basic
  • 从常量引用中移动构造

    我遇到以下情况 需要从 t1 中移动构造 t2 不幸的是 这是不可能的 我想是违反常量的 从 foo 的调用者那里透明地处理这个问题的正确方法是什么 即不需要传值和显式 std move struct T T default T defau
  • 删除元素时映射迭代器如何失效? [复制]

    这个问题在这里已经有答案了 使用擦除方法时 迭代器何时以及如何在映射中失效 例如 std map lt int int gt aMap aMap 33 1 aMap 42 10000 aMap 69 100 aMap 666 1 std m
  • GCC 4.7.2:带有指向成员函数指针的 std::thread

    在编写测试代码时这个问题 https stackoverflow com questions 15080015 stdthread with pointer to data member我发现下面的注释行无法在 GCC 4 7 2 上编译
  • 按const值返回会影响返回值优化吗? [复制]

    这个问题在这里已经有答案了 考虑功能 const std string f return hello 还有那通电话 std string x f 无论值返回类型是否应为 const 返回值是 const 的事实是否会阻止编译器执行返回值优化
  • 将Pycharm项目移动到另一个目录

    我的主目录空间不足 我想将 PyCharm 项目移动到另一个目录 我最终复制了它 因为重构不起作用 我删除了 pycache 和 zip 异常 出现的异常消失了 现在一切都按预期工作 不过 从 settings python interpr
  • CSS - 将文本保留在图像下方

    我正在尝试创建一个简单的图片库 有人告诉我使用 float left 但是当我这样做时 页脚中的所有文本都会射到第一张图像 我已经搜索了大约一个小时试图找到解决方案 但我找不到任何东西 我尝试过使用边距 边框 不同的对齐方式和各种不同的小东
  • 如何使用 CUDA/Thrust 对两个数组/向量根据其中一个数组中的值进行排序

    这是一个关于编程的概念问题 总而言之 我有两个数组 向量 我需要对一个数组 向量进行排序 并将更改传播到另一个数组 向量中 这样 如果我对 arrayOne 进行排序 则对于排序中的每个交换 arrayTwo 也会发生同样的情况 现在 我知
  • C++ 长 switch 语句还是用地图查找?

    在我的 C 应用程序中 我有一些值充当代表其他值的代码 为了翻译代码 我一直在争论使用 switch 语句还是 stl 映射 开关看起来像这样 int code int value switch code case 1 value 10 b
  • std::在 std::string 和 std::vector 之间移动

    我正在与 2 个图书馆合作 一个接受并返回std strings 而其他使用std vector
  • Android ACTION_MOVE阈值

    我正在编写一个应用程序 需要使用手指或最终使用手写笔在屏幕上书写 我有那部分工作 在 ACTION DOWN 时 开始绘制 在 ACTION MOVE 上 添加线段 在 ACTION UP 上 完成该行 问题是 在 ACTION DOWN
  • 为什么 std::vector 可以处理类定义中的不完整类型?

    出现了以下问题 C 标准似乎说 std vector需要一个完整的类型才能工作 看https en cppreference com w cpp container vector https en cppreference com w cp
  • std::vector 的复制构造函数如何运行?

    一个如何std vector

随机推荐

  • 浅谈UML学习笔记动态模型之序列图、协作图

    1 序列图 序列图和协作图都是交互图 xff0c 彼此等价 xff0c 可以相互转化 序列图是对对象之间传送消息的时间顺序的可视化表示 序列图用于表现交互 xff0c 侧重于强调时间顺序 序列图将交互关系表示为一个二维图 xff0c 如下图
  • No valid host was found. There are not enough hosts available

    root 64 dell PowerEdge T30 nova boot flavor m1 tiny image cirros nic net id 61 c2943fac a910 4cf6 b021 e8ab321965c9 secu
  • 校园网频繁断线、连不上网etc.

    这篇记录一下 Windows 下安装完 虚拟机 之后 xff0c 校园网 xff08 和其他网络 xff09 断线 xff0c 甚至无法连接到网络的情况 背景 xff1a 新装的系统 xff0c 网卡驱动什么的也都是刚装好的 xff0c 虚
  • JavaScript 笔记(3) -- JSON

    JavaScript JSON JavaScript Object Notation 是一种轻量级的数据交换格式 JSON 是用于存储和传输数据的格式JSON 通常用于服务端向网页传递数据 JSON 使用 JavaScript 语法 xff
  • 【转载】Notepad++使用技巧

    一 安装notepad 43 43 notepad 43 43 的下载 安装非常easy 下一步下一步 xff0c 所有选项都默认就可以安装好 但有几点需要注意 截止到写这篇博文 xff0c notepad 43 43 的最新版本为7 5
  • 0.1+0.2为什么不等于0.3

    首先 xff0c 对于不同的进制数值系统 xff0c 分母为多少时能除干净 xff1f 答案是当以前进制数的质因子为分母时 xff0c 以十进制为例 xff0c 它的质因子为2 5 xff0c 因此1 2 1 4 1 5 1 8和 1 10
  • git tag

    git tag的用法 git的tag功能 git 下打标签其实有2种情况 轻量级的 xff1a 它其实是一个独立的分支 或者说是一个不可变的分支 指向特定提交对象的引用带附注的 xff1a 实际上是存储在仓库中的一个独立对象 xff0c 它
  • 对web前端这门课程的期望

    对于这门课程 xff0c 我只希望我能过就行 xff0c 因为我将来可能不会从事着方面的工作 xff0c 但为了丰富自己的知识 xff0c 我还是觉得要认真的对待每一门学科 xff0c 这一门也不例外 xff0c 我希望我可以学的尽量好一点
  • ArcEngine安装并注册后应用程序无法使用toc等控件的解决办法

    安装了ArcEngine xff0c 并且用ecp注册过 但当放置toolbarcontrol TOCControl等控件在窗体上时 xff0c 提示 this control require an esri designer licens
  • Debian中安装使用sudo命令

    Debian中安装使用sudo命令 sudo可以让非root用户具有管理员的权限 xff0c 安装好的Debian后还不能使用sudo 需要使用root用户登陆后安装sudo命令 span style color 000102 span s
  • linux breakpad 编译,linux 平台编译googlebreakpad并测试 demo

    Linux googlebreakpad 编译 1 下载源码 源码包括两部分 xff0c 分为依赖库和 breakpad xff0c 网址一般会被屏蔽 xff0c 需要墙一下 另 xff0c 编译器需要支持 c 43 43 11 我用的gc
  • 233

    include lt bits stdc 43 43 h gt define reg register int define il inline define fi first define se second define mk a b
  • 再探容斥好题——ROOK

    这个时候考过 xff1a 安师大附中集训 Day2 当时看shadowice1984的做法 xff0c 但是没有亲自写 xff0c xff0c xff0c 雅礼集训考试的时候鼓捣半天 xff0c 被卡常到80pts xff0c 要跑9s 卡
  • CF908G New Year and Original Order

    CF908G New Year and Original Order gzz讲过 xff0c 可我到今天还是不会 有点trick的数位DP 比较显然的思路是 xff0c 考虑所有数中排序后每一位的贡献 cnt i x 表示S 1 S x 第
  • 本地在不安装Oracle的情况下安装PLSQL客户端

    本文解决问题 xff1a 通常在本地安装PLSQL后 xff0c 如果本地没有安装Oracle数据库的话 xff0c PLSQL是不能使用的 xff0c 输入远程数据库登录信息会提示 xff1a Oracle Client没有正确安装 这个
  • Ubuntu的中文乱码问题

    目标 xff1a 使系统 服务器支持中文 xff0c 能够正常显示 1 首先 xff0c 安装中文支持包language pack zh hans xff1a sudo apt get install language pack zh ha
  • Python argparse 处理命令行小结

    Python argparse 处理命令行小结 1 关于argparse 是python的一个命令行解析包 xff0c 主要用于处理命令行参数 2 基本用法 test py是测试文件 xff0c 其内容如下 import argparse
  • 分布式系统心跳协议的设计

    分布式系统心跳协议的设计 应用层心跳必不可少 xff1a 1 操作系统崩溃导致机器重启 没有机会发送 FIN 分节 2 服务器硬件故障导致机器重启 也没有机会发送 FIN 分节 3 并发连接数很高时 操作系统或进程如果重启 可能没有机会断开
  • malloc vs memset

    malloc vs memset OS内存分配过程如下 xff1a 用户态程序使用malloc接口 xff0c 分配虚拟地址 用户程序访问该虚拟地址 xff0c 比如memset 硬件 xff08 MMU xff09 需要将虚拟地址转换为物
  • c++ rvo vs std::move

    c 43 43 rvo vs std move To summarize RVO is a compiler optimization technique while std move is just an rvalue cast whic