c++ rvo vs std::move

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值