如我错了请纠正我.说我有:
struct X
{
std::string mem_name;
X(std::string name)
: mem_name(std::move(name))
{}
...
};
struct Y
{
std::string mem_name;
Y(const std::string &name)
: mem_name(name)
{}
...
};
Run Code Online (Sandbox Code Playgroud)
在X
ctor中,name
显然是传递给任何参数的副本X
,X
调用std::string
初始化的移动mem_name
,对吧?
让我们称之为X*的复制然后移动 ; 两个操作:COPY,MOVE.
在Y
's ctor中,name
是一个const ref,这意味着没有元素的实际副本,因为我们直接处理从Y
需要创建对象的地方传递的参数.但是,我们复制name
到初始化mem_name
的Y
; 一个操作:COPY.因此它应该更快(对我来说更好)?
在Scott Meyer的GN13演讲中(围绕时间框架8:10和8:56),他谈到了"想要速度?通过价值传递",我想知道在传递参数时是否有任何性能差异或损失(或者字符串是准确的)通过引用和传递值"以获得速度?"
我知道按值传递参数可能很昂贵,特别是在处理大数据时.
也许(显然?)我的谈话中缺少一些东西?
Rei*_*ica 57
"想要速度?通过价值" (1)的想法是,有时,副本可以省略.上课,X
并Y
考虑这个用例:
// Simulating a complex operation returning a temporary:
std::string foo() { return "a" + std::string("b"); }
struct X
{
std::string mem_name;
X(std::string name): mem_name(std::move(name)) {}
};
struct Y
{
std::string mem_name;
Y(const std::string &name): mem_name(name) {}
};
int main()
{
X(foo());
Y(foo());
}
Run Code Online (Sandbox Code Playgroud)
现在让我们分析一下构造案例.
X
第一.foo()
返回一个临时的,用于初始化对象name
.然后将该对象移入mem_name
.请注意,编译器可以应用返回值优化并直接在空间中构造返回值foo()
(实际上甚至是返回值operator+
).因此,实际上不会发生复制,只是一次移动.name
现在让我们来分析吧Y
.foo()
再次返回一个临时的,绑定到引用name
.现在返回值没有"外部提供的"空间,因此必须在自己的空间中构造并绑定到引用.然后将其复制到mem_name
.所以我们正在做一个副本,没有办法解决它.
简而言之,结果是:
如果左值被传入,都X
和Y
将执行复制(X
初始化时name
,Y
初始化时mem_name
).此外,X
将执行移动(初始化时mem_name
).
如果传入右值,X
则可能只执行移动,而Y
必须执行复制.
通常,移动预期是一种操作,其时间要求与传递指针(通过引用传递的内容)相当.因此,实际上,X
并不比Y
左值更差,对于右值更好.
当然,这不是一个绝对的规则,必须采取一些盐.如有疑问,请查看.
(1)该链接容易暂时不可用,并且从2014年12月12日起,它似乎被打破(404).几个博客网站上似乎提供了内容的副本(尽管有奇怪的格式):
或者,可以通过返回机器访问原始内容.
另请注意,该主题总体上激起了相当多的讨论.谷歌搜索文章标题带来了很多后续和反点.为了列举其中一个例子,SO成员juanchopanza有"想要速度吗?不要(总是)超值"
归档时间: |
|
查看次数: |
12778 次 |
最近记录: |