据我所知,在使用RVO的C ++ 11中,按价值返回的东西更好。 我做了一些性能测试,我只是在一个循环(300000000循环)中调用GetVector()方法,并在另一个类的向量上写入值(Vecto应该在两个类中仍然可用):函数调用:
vector<string> myvec = myObjec.GetVec();
让我们带一个大约50 std :: strings的容器:
OS-X上的编译器LLVM C ++ 11支持
vector<string> vec;
vector<string> GetVector()
{
return vec;
}
在C ++ 11支持下,按值返回比按引用返回更快。
编译器GNU C ++
使用此编译器按引用返回比按值返回更快,并且通过引用返回也比使用C ++ 11 LLVM按值返回快得多。
问题1:由于RVO,GNU C ++在这里的速度是否更快,或者C ++ 11在返回值时通常更慢?
我的下一个问题:
我用指针测试了相同的例子,这是我测试中最快的方法:
vector<string> vec;
vector<string>* GetVector()
{
return &vec;
}
调用该函数:
vector<vec>* vec;
vec = myObj.GetVector();
这个例子非常快,但我听说从长远来看会搞乱内存管理,但为什么呢?
第三个问题:
如果使用原始点是一个不好的例子我至少会使用smart_pointers,它们在某种程度上不如原始指针那么快(认为这是因为shared_ptr)但仍然比仅按值返回要快得多,但在一些文章中我和#39;我读过它是一个糟糕的例子,只是弄乱了我的代码。但是为什么使用智能指针会不好?
答案 0 :(得分:3)
此代码中没有涉及RVO:
vector<string> vec;
vector<string> GetVector()
{
return vec;
}
因为vec
仍然可用,因此您可以修改vec
并独立返回GetVector()
的值。因此,编译器必须创建vec
。
更正式地说,C ++ 11/14标准部分12.8/31
说:
(...)在下列情况下(可以合并以消除多份副本),允许复制/移动操作的省略,称为复制省略: - 在具有类返回类型的函数的
的目标中return
语句中,当表达式是非易失性自动对象(函数或catch子句参数除外)的名称时与函数返回类型相同的cv-unqualified类型,通过将自动对象直接构造为函数的返回值,可以省略复制/移动操作 (...)
- 当未绑定到引用(12.2)的临时类对象将被复制/移动时 对于具有相同cv-unqualified类型的类对象,可以省略复制/移动操作 将临时对象直接构造到省略的复制/移动
C ++ 98标准在12.8/15
中表示基本相同(移动除外)。
这意味着只有在返回局部变量或临时对象时才应用RVO。