-3

After testing this code:

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

I get that using const-reference is actually ~15s faster than using move semantics, why is that? I thought that move semantics were faster, else, why would they add them? What did I get wrong about move semantics? thanks

4

1 回答 1

2

你的代码没有意义。这是您的代码的更简单版本,已替换int并清理。这是代码的汇编版本,编译为-std=c++11 -02

https://goo.gl/6MWLNp

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

原因可能是因为编译器将这两个函数优化为同一个程序集。你没有对任何一个做任何事情,所以在程序集中做任何不同于简单的ret.

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

https://goo.gl/Sp6sk4

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

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


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

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

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

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

于 2015-10-13T02:15:48.043 回答