c++ Return 价值优化
c++ Return Value Optization
我希望有人能阐明 RVO 在 g++ 中的作用。我有一些需要修改的第三方软件,我想尽可能地优化它,但我无法弄清楚 RVO 到底做了什么,以及它何时启动。我当前的结构如下所示:
class Foo {
private:
Bar myBar;
public:
Bar &getBar() { return myBar; };
};
呼叫者通常这样使用它的地方:
int x = foo.getBar().getX();
因为 return 是引用,所以不需要结构的副本,出于性能原因,这很好。
我需要修改 Foo
以使用 Bar2
而不是 Bar
作为其内部结构,但是,我需要保持 getBar()
接口可用于第三个派对来电者。我有一个函数convertBar2ToBar(const struct Bar2 &bar2, struct Bar &bar)
,它可以在两种结构类型之间高效地转换,但我很担心,好像我这样做:
Bar& Foo::getBar() { Bar rt; convertBar2ToBar(myBar2, rt); return rt }
然后这个return是对栈上变量的引用,可以在上面乱写。我也可以将程序修改为 return rt
的副本:
Bar Foo::getBar() { Bar rt; convertBar2ToBar(myBar2, rt); return rt }
但现在我担心我的Foo.getBar().getX()
会很慢,因为它必须将Bar2
转换为rt
(不可避免),然后复制'rt' 到调用者的本地上下文(可避免???)...我不清楚 RVO 是否可以阻止复制,如果可以,那么幕后到底发生了什么。
I'm not clear whether RVO can prevent the copy
是的,这就是它的目的。
此外,从 C++17 开始,需要 来防止复制。
(抱歉,不,不是;那是为了 return 一个纯右值;不过,实际上你可以依赖 NRVO)
如果复制品的价格足以让我们一开始就关心这些,那么它可能也应该是可移动的,在这种情况下我们又不会关心成本。
and if so, what exactly is going on under the hood.
没关系。
但是,在您的 2017 PC 上,粗略地说,rt
将 "created" 在调用者的堆栈框架中,而不是在本地。因此,根本不需要复制。
(而且,确实,不要 return 对局部变量的引用。)
我希望有人能阐明 RVO 在 g++ 中的作用。我有一些需要修改的第三方软件,我想尽可能地优化它,但我无法弄清楚 RVO 到底做了什么,以及它何时启动。我当前的结构如下所示:
class Foo {
private:
Bar myBar;
public:
Bar &getBar() { return myBar; };
};
呼叫者通常这样使用它的地方:
int x = foo.getBar().getX();
因为 return 是引用,所以不需要结构的副本,出于性能原因,这很好。
我需要修改 Foo
以使用 Bar2
而不是 Bar
作为其内部结构,但是,我需要保持 getBar()
接口可用于第三个派对来电者。我有一个函数convertBar2ToBar(const struct Bar2 &bar2, struct Bar &bar)
,它可以在两种结构类型之间高效地转换,但我很担心,好像我这样做:
Bar& Foo::getBar() { Bar rt; convertBar2ToBar(myBar2, rt); return rt }
然后这个return是对栈上变量的引用,可以在上面乱写。我也可以将程序修改为 return rt
的副本:
Bar Foo::getBar() { Bar rt; convertBar2ToBar(myBar2, rt); return rt }
但现在我担心我的Foo.getBar().getX()
会很慢,因为它必须将Bar2
转换为rt
(不可避免),然后复制'rt' 到调用者的本地上下文(可避免???)...我不清楚 RVO 是否可以阻止复制,如果可以,那么幕后到底发生了什么。
I'm not clear whether RVO can prevent the copy
是的,这就是它的目的。
此外,从 C++17 开始,需要 来防止复制。
(抱歉,不,不是;那是为了 return 一个纯右值;不过,实际上你可以依赖 NRVO)
如果复制品的价格足以让我们一开始就关心这些,那么它可能也应该是可移动的,在这种情况下我们又不会关心成本。
and if so, what exactly is going on under the hood.
没关系。
但是,在您的 2017 PC 上,粗略地说,rt
将 "created" 在调用者的堆栈框架中,而不是在本地。因此,根本不需要复制。
(而且,确实,不要 return 对局部变量的引用。)