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(使用前将#替换为@)