Andrew Koenig撰写了一篇文章,题为" 一些优化比其他人更重要",其中包含以下两个函数定义:
string rev(string s) {
reverse(s.begin(), s.end());
return s; // GCC-4.8 uses move constructor
}
string rev(string&& s) {
reverse(s.begin(), s.end());
return s; // GCC-4.8 uses copy constructor
}
Run Code Online (Sandbox Code Playgroud)
文章暗示第二个函数(与const string&重载相结合)比第一个函数更有效.然而,当我用GCC-4.8进行测试时,这不是我所看到的.第一个函数在语句中移动对象s,return而第二个函数复制对象.如果我将第二个函数中的return语句更改为return move(s);,则在两种情况下都将移动该对象.
问题:可以在语句中自动移动哪些参数return?更具体地说,声明为非const rvalue-references的参数是否可以自动移动?
唯一可以通过return语句自动移动的东西是变量:
#3删除了任何类型的引用.如果你想从一个引用移动,你必须明确地说要从它移动.
但是,如果你想知道为什么后者会更有效率,那么它与移动次数有关.
在第一种情况下,您可以复制/移动到函数参数中s.用户必须将某些字符串复制或移动到参数中.然后参数的数据被移回.
在第二种情况下,您既没有复制也没有进入函数参数; 它只是引用一个现有的对象.如果用户调用右值参考版本,则只有一个副本超出参数.
所以第一种情况有一个副本/移动和一个移动,而不是一个副本.因此,如果用户正在复制参数,由于额外的移动,您的第一个案例将会变慢.
运动不是免费的.它可能便宜(相对于复制),但它不是免费的.2个移动比1更贵.如果用户调用const&版本,则表示他们要求复制字符串.所以他们得到一份副本,然后几乎肯定会被删除.
就个人而言,我会将较小的效率增益与两次实施相同功能的重大问题进行权衡.在某些情况下,它可能是值得的.但我不会理所当然地这样做.
| 归档时间: |
|
| 查看次数: |
125 次 |
| 最近记录: |