测试此代码后:
#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实际上比使用移动语义快〜15s,为什么会这样?我认为移动语义更快,否则,他们为什么要添加它们?关于移动语义我有什么问题?感谢
答案 0 :(得分:1)
你的代码毫无意义。这是一个更简单的代码版本,替换为int
并进行了清理。以下是使用-std=c++11 -02
编译的代码的汇编版本:
rvalue和左值函数的程序集之间没有区别。原因是什么并不重要,因为测试本身并没有使用移动语义。 / p>
原因可能是因为编译器优化了同一个程序集的两个函数。你们两个都没有做任何事情,所以在做任何不同的事情上都没有意义。汇编而不是简单的ret
。
这是一个更好的例子,这一次,交换向量中的前两项:
具有讽刺意味的是,您可以看到第二个函数实际上只是自动调用右值参考版本作为其执行的一部分。
假设调用B的函数A比执行函数B慢,x()
的速度应该优于y()
。
std::move()
本身需要支付额外费用。其他所有内容都是不变的,调用std::move()
比调用std::move()
更加昂贵。这就是&#34;移动语义&#34;在你给我们的代码中速度较慢。 实际上,代码较慢,因为您实际上并没有做任何事情 - 这两个函数只是在执行后立即返回。您还可以看到一个版本似乎呼叫std::move()
而另一个版本没有。
编辑:上述情况似乎并非如此。 std::move()
通常不是真正的函数调用;主要是static_cast<T&&>
取决于某些模板内容。
在我给你的例子中,我实际上是在利用移动语义。大多数程序集更重要,但您可以看到y()
调用x()
作为其执行的一部分。因此,y()
应该比x()
慢。
tl;博士:您实际上并没有使用移动语义,因为您的功能根本不需要做任何事情。使函数使用复制/移动,您将看到即使是程序集也使用了部分&#34;移动语义&#34;代码作为其复制代码的一部分。