C++ RVO&返回一个容器

C++ RVO&返回一个容器,c++,performance,c++11,C++,Performance,C++11,据我所知,在使用RVO的C++11中,最好按值返回内容。 我做了一些性能测试,我只是在一个loop300000000循环中调用一个GetVector方法,并在另一个classVecto中的向量上写入值,这两个类中Vecto应该仍然可用:函数调用: vector<string> myvec = myObjec.GetVec(); 让我们看一个包含大约50个std::字符串的容器: OS-X上的编译器LLVM C++11支持 vector<string> vec; vect

据我所知,在使用RVO的C++11中,最好按值返回内容。 我做了一些性能测试,我只是在一个loop300000000循环中调用一个GetVector方法,并在另一个classVecto中的向量上写入值,这两个类中Vecto应该仍然可用:函数调用:

vector<string> myvec = myObjec.GetVec();
让我们看一个包含大约50个std::字符串的容器:

OS-X上的编译器LLVM C++11支持

vector<string> vec;
vector<string> GetVector()
{
 return vec;
}
有了C++11支持,按值返回比按引用返回快

编译器GNUC++


使用此编译器,通过引用返回比通过值返回快,并且通过引用返回也比使用C++11 LLVM通过值返回快得多

问题1:GRU C++在这里更快,还是C++ 11在返回值方面更慢,因为RVO?

我的下一个问题:

我用指针测试了相同的示例,指针是我测试中最快的方法:

vector<string> vec;
vector<string>* GetVector()
{
 return &vec;
}
调用函数:

vector<vec>* vec;
vec = myObj.GetVector();
这个例子非常快,但我听说从长远来看它会破坏内存管理,但为什么呢

第三个问题:


如果使用原始点是一个糟糕的例子,我至少会使用智能指针,但它们的速度不如原始指针。我认为这是因为共享的ptr,但仍然比按值返回快得多,但在一些文章中,我读到这是一个糟糕的例子,只是把我的代码搞乱了。但是为什么使用智能指针会不好呢?

此代码中没有RVO:

vector<string> vec;
vector<string> GetVector()
{
    return vec;
}
因为vec仍然可用,所以您可以单独修改vec和GetVector的返回值。因此,编译器必须创建vec的副本

更正式地说,C++11/14标准第12.8/31节说:

。。。在以下情况下,允许省略复制/移动操作(称为复制省略),这些情况可以组合起来消除多个副本: -在具有类返回类型的函数中的return语句中,如果表达式是非易失性自动对象的名称,而不是与函数返回类型具有相同cv非限定类型的函数或catch子句参数,通过将自动对象直接构造到函数的返回值中,可以省略复制/移动操作 ... -复制/移动未绑定到参考12.2的临时类对象时 对于具有相同cv类型的类对象,可以通过 将临时对象直接构造到省略的复制/移动的目标中

C++98标准说基本上是一样的,除了在12.8/15中移动


这意味着RVO仅在返回局部变量或临时对象时适用。

RVO不限于c++11。通过引用返回也比使用c++11 LLVM通过值返回快得多在这之前的几行代码中,您断言了OS-X上完全相反的编译器LLVM C++11支持,有了C++11支持,按值返回比按引用返回快。。我无法理解你的任何问题,它的语法非常糟糕,非常不连贯。你刚才不是问了吗?有意义的基准测试非常困难-你应该发布代码,这样我们就可以验证你做得是否正确。从你在这个问题和Kerrek links的另一个问题中的观点来看,很可能你在基准测试中犯了一些重大错误……RVO在哪里?RVO是为返乡的当地人准备的。我认为编译器、人类或squid无法避免代码中的副本。嗯,我听说,它不会创建副本,但是相反,对象直接构造在函数所在的位置invoked@Sleicreider请阅读我的说明,返回容器的最佳和最快解决方案是什么?@Sleicreider取决于您的需要。因为当客户端指针超出范围时,未分配新的原始向量将通过删除释放,导致未定义行为的。