“想要速度”有多真实?按价值传递” [英] How true is "Want Speed? Pass by value"

查看:64
本文介绍了“想要速度”有多真实?按价值传递”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我错了,请纠正我。假设我有:

Correct me if I'm wrong. Say I have:

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 的移动ctor来初始化 mem_name ,对吗?

In X's ctor, name is obviously a copy of whatever argument got passed to X, X invokes the move ctor of std::string to initialize mem_name, right?

我们称​​在X *上复制然后移动;两项操作:复制,移动

Y 的ctor中, name 是一个const ref,这意味着该元素没有实际的副本,因为我们直接处理从 Y 的对象需要创建。但是随后我们复制了 name ,以在 Y 中初始化 mem_name ;一种操作:复制。因此,它肯定应该更快(并且对我来说更好)吗?

In Y's ctor, name is a const ref, which means there's no actual copy of the element because we're dealing directly with the argument passed from wherever Y's object needs to be created. But then we copied name to initialise mem_name in Y; one operation: COPY. Surely it should therefore be a lot faster (and preferable to me)?

在斯科特·迈耶(Scott Meyer)的GN13演讲中(大约时间8:10和8:56),他谈论想要速度?按值传递 ,我想知道通过引用传递值(或精确的字符串)和按值传递以获取速度是否存在性能差异或损失? ?

In Scott Meyer's GN13 talk (around time-frame 8:10 and 8:56), he talks about "Want speed? Pass by value" and I was wondering is there any performance difference or loss in passing arguments (or strings to be precise) by reference and passing by value "in order to gain speed?"

我知道以下事实:按值传递参数可能会很昂贵,尤其是在处理大数据时。

I'm aware of the fact that passing arguments by value can be expensive, especially when dealing with large data.

也许(很明显?)他的谈话中我遗漏了一些东西?

Maybe (clearly?) there's something I'm missing from his talk?

推荐答案

想要速度吗?按值传递 (1)表示有时可以删除副本。以您的类 X Y 为例,考虑以下用例:

The idea of "Want speed? Pass by value"(1) is that sometimes, the copy can be elided. Taking your classes X and Y, consider this usecase:

// 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());
}

现在让我们分析两个构造案例。

Now let's analyse both the construction cases.

X 首先。 foo()返回一个临时变量,用于初始化对象 name 。然后将该对象移到 mem_name 中。请注意,编译器可以应用返回值优化并构造 foo()的返回值(实际上甚至是 operator + )直接 放在 name 的空格中。因此,实际上并没有发生复制,只有一个动作。

X first. foo() returns a temporary, which is used to initialise the object name. That object is then moved into mem_name. Notice that the compiler can apply Return Value Optimisation and construct the return value of foo() (actually even the return value of operator+) directly in the space of name. So no copying actually happens, only a move.

现在让我们分析 Y foo()再次返回一个临时文件,该临时文件绑定到引用 name 。现在没有用于返回值的外部提供空间,因此必须将其构造在自己的空间中并绑定到引用。然后将其复制到 mem_name

Now let's analyse Y. foo() returns a temporary again, which is bound to the reference name. Now there's no "externally supplied" space for the return value, so it has to be constructed in its own space and bound to the reference. It is then copied into mem_name. So we are doing a copy, no way around it.

总之,结果是:


  • 如果传入左值,则 X Y 都将执行复制( X 初始化 name Y 初始化 mem_name )。此外, X 将执行移动(初始化 mem_name 时)。

  • If an lvalue is being passed in, both X and Y will perform a copy (X when initialising name, Y when initialising mem_name). In addition, X will perform a move (when initialising mem_name).

如果传入右值,则 X 可能仅执行移动,而 Y 必须执行复制。

If an rvalue is being passed in, X will potentially only perform a move, while Y has to perform a copy.

通常,移动是一项需要时间比较的操作传递指针(通过引用传递)。因此,实际上,对于$左值, X 不比 Y 差,对于右值来说更好。

Generally, a move is expected to be an operation whose time requirements are comparable to those of passing a pointer (which is what passing by reference does). So in effect, X is no worse than Y for lvalues, and better for rvalues.

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

Of course, it's not an absolute rule, and must be taken with a grain of salt. When in doubt, profile.

(1)链接暂时不可用,从11-12开始-2014,它似乎已损坏(404)。内容的副本(尽管格式很奇怪)似乎在几个博客站点上可用:

(1) The link is prone to being temporarily unavailable, and as of 11-12-2014, it seems broken (404). A copy of the contents (albeit with weird formatting) seems available at several blog sites:

  • blog on csdn.net
  • blog on blogspot.cz

或者,也可以通过回溯机器

还请注意,该主题通常具有引起了相当多的讨论。谷歌搜索纸质标题带来了很多后续行动和对策。要列举其中一个示例,请参见 SO成员 juanchopanza

Also note that the topic has in general stirred up quite a discussion. Googling the paper title brings up a lot of follow-ups and counter-points. To list an example of one of these, there's "Want speed? Don't (always) pass by value" by SO member juanchopanza

这篇关于“想要速度”有多真实?按价值传递”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆