C++,常量引用实际上比移动更快



测试此代码后:

#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() << " secondsn";
    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() << " secondsn";
    std::cin.get();
}

我知道使用 const 引用实际上比使用移动语义快 ~15 秒,为什么会这样?我认为移动语义更快,否则,他们为什么要添加它们?我在移动语义方面做错了什么?谢谢

你的代码没有意义。下面是代码的更简单版本,替换为 int 并进行了清理。以下是代码的汇编版本,使用 -std=c++11 -02 编译:

https://goo.gl/6MWLNp

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

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

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

https://goo.gl/Sp6sk4

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

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


std::move()本身需要额外付费。所有其他事情都是恒定的,调用std::move()比不调用std::move()的成本更高。这就是为什么您提供给我们的代码中的"移动语义"较慢的原因。实际上,代码速度较慢,因为您实际上并没有执行任何操作 - 这两个函数在执行后立即返回。您还可以看到一个版本似乎调用std::move()而另一个版本没有。

编辑:以上似乎不是真的。 std::move()通常不是真正的函数调用;它主要是一个依赖于一些模板内容的static_cast<T&&>

在我

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

dr:你实际上并没有使用移动语义,因为你的函数根本不需要做任何事情。使函数使用复制/移动,您将看到甚至程序集也使用"移动语义"代码的一部分作为其复制代码的一部分。

相关内容

最新更新