【问题标题】:C++, const reference is actually faster than move?C++, const 引用实际上比 move 快吗?
【发布时间】:2023-03-13 07:22:01
【问题描述】:

测试此代码后:

#include <iostream>
#include <chrono>
#include <vector>
#include <string>


void x(std::vector<std::string>&& v){ }

void y(const std::vector<std::string>& v) { }

int main() {
    std::vector<std::string> v = {};

    auto tp = std::chrono::high_resolution_clock::now();

    for (int i = 0; i < 1000000000; ++i)
        x(std::move(v));

    auto t2 = std::chrono::high_resolution_clock::now();

    auto time = std::chrono::duration_cast<std::chrono::duration<double>>(t2 - tp);

    std::cout << "1- It took: "  << time.count() << " seconds\n";

    tp = std::chrono::high_resolution_clock::now();

    for (int i = 0; i < 1000000000; ++i)
        y(v);

    t2 = std::chrono::high_resolution_clock::now();

    time = std::chrono::duration_cast<std::chrono::duration<double>>(t2 - tp);

    std::cout << "2- It took: " << time.count() << " seconds\n";

    std::cin.get();
}

我知道使用 const-reference 实际上比使用移动语义快约 15 秒,这是为什么呢?我认为移动语义更快,否则,他们为什么要添加它们?我对移动语义有什么误解?谢谢

【问题讨论】:

  • 你的函数是空的,除了参数传递设置之外你没有测试任何东西——也就是说,如果调用没有完全优化。也许一个得到优化而另一个没有?您应该查看或发布生成的代码。
  • 您的x 采用&amp;&amp; 这一事实表明您不了解移动语义。考虑阅读this question and answers
  • 移动是对 copy 的优化(对于 xvalues),而不是通过引用传递。当然传递一个简单的引用会更快。
  • 你开启优化了吗?

标签: c++ c++11 constants move const-reference


【解决方案1】:

您的代码毫无意义。这是您的代码的更简单版本,替换为int 并进行了清理。这是代码的汇编版本,用-std=c++11 -02编译:

https://goo.gl/6MWLNp

右值和左值函数的程序集没有区别。无论是什么原因都无关紧要,因为测试本身不使用移动语义。

原因可能是因为编译器将这两个函数优化为同一个程序集。您没有对任何一个函数做任何事情,因此在程序集中做任何与简单的 @987654325 不同的事情都没有意义@。

这是一个更好的例子,这一次,交换向量中的前两项:

https://goo.gl/Sp6sk4

具有讽刺意味的是,您可以看到第二个函数实际上只是自动调用右值引用版本作为其执行的一部分。

假设调用 B 的函数 A 比仅执行函数 B 慢,则 x() 的速度应该优于 y()


std::move() 本身有额外的费用。其他一切都保持不变,调用std::move() 比不调用std::move() 更昂贵。这就是您给我们的代码中“移动语义”较慢的原因。 实际上,代码比较慢,因为您实际上并没有做任何事情——这两个函数都只是在执行后立即返回。您还可以看到一个版本似乎调用了std::move(),而另一个没有。

编辑:上述情况似乎不正确。 std::move() 通常不是真正的函数调用;它主要是一个static_cast&lt;T&amp;&amp;&gt;,它依赖于一些模板的东西。

在我给你的例子中,我实际上使用了移动语义。大多数程序集更重要,但您可以看到y() 调用x() 作为其执行的一部分。因此y() 应该比x() 慢。

tl;dr:您实际上并没有使用移动语义,因为您的函数根本不需要做任何事情。让函数使用复制/移动,您会看到即使是程序集也使用部分“移动语义”代码作为其复制代码的一部分。

【讨论】:

  • 您确定调用 move 需要付费吗?我以为这只是重新诠释演员表;它没有运行时成本,并且函数本身将被内联,因此没有开销。
  • 感谢您礼貌地回答。我会考虑到这一切,汇编代码让我很清楚。再次感谢。
  • @NirFriedman 是的,你是对的;我更改了帖子以反映这一点
猜你喜欢
  • 1970-01-01
  • 2017-11-06
  • 1970-01-01
  • 2011-12-07
  • 2014-03-29
  • 2013-12-30
  • 2016-03-09
  • 1970-01-01
  • 2013-02-01
相关资源
最近更新 更多