c – “真的是”想要速度?通过值“

如我错了请纠正我。说我有:

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) 
    {}
    ...
};

在X的ctor中,name显然是传递给X的任何参数的副本,X调用std :: string的move ctor来初始化mem_name,对吧?

让我们称之为X *上的copy-then-move;两个操作:COPY,MOVE。

在Y的ctor中,name是一个const引用,这意味着没有元素的实际副本,因为我们直接处理从需要创建Y的对象传递的参数。但是我们复制名字在Y中初始化mem_name;一个操作:COPY。当然,它应该是快得多(和我更喜欢)?

在Scott Meyer的GN13演讲中(约在时间框架8:10和8:56),他谈到“想要速度传递价值”,我想知道是否有任何性能差异或丢失传递参数(或字符串要精确)通过参考并通过值“为了获得速度?

我知道这样的事实,通过价值传递参数可能是昂贵的,特别是在处理大数据时。

也许(显然?)有一些我从他的谈话中失踪?

“Want speed? Pass by value”(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());
}

现在让我们分析这两个建筑案例。

X先。 foo()返回一个临时的,用于初始化对象名。然后将该对象移动到mem_name中。注意,编译器可以应用返回值优化,并且在名称空间中直接构造foo()的返回值(实际上甚至操作符的返回值)。所以没有复制实际发生,只有一个移动。

现在让我们分析Y. foo()返回一个临时,它绑定到引用名称。现在没有用于返回值的“外部提供”空间,因此它必须在自己的空间中构造并绑定到引用。然后将其复制到mem_name中。所以我们做一个副本,没有办法。

简而言之,结果是:

>如果传递一个左值,X和Y都将执行一个副本(初始化名称时为X,初始化mem_name时为Y)。此外,X将执行移动(初始化mem_name时)。
>如果传入右值,X将可能只执行移动,而Y必须执行复制。

通常,期望移动是其时间要求与传递指针(其通过引用传递的那些)相当的操作。因此,实际上,对于左值,X不比Y更差,对右值更好。

当然,这不是一个绝对的规则,必须用一粒盐。当有疑问,配置文件。

(1)链路容易暂时不可用,并且从11-12-2014,它似乎破碎(404)。内容的副本(虽然有奇怪的格式)似乎可在几个博客网站:

> blog on csdn.net
> blog on blogspot.cz

或者,原始内容可以通过wayback machine访问。

还要注意的是,这个话题通常引起了相当多的讨论。 Googling的论文标题带来了很多后续和对立点。要列出其中一个的示例,有“Want speed? Don’t (always) pass by value”的SO成员juanchopanza

http://stackoverflow.com/questions/21605579/how-true-is-want-speed-pass-by-value

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:c – “真的是”想要速度?通过值“