测试此代码后:
#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:你实际上并没有使用移动语义,因为你的函数根本不需要做任何事情。使函数使用复制/移动,您将看到甚至程序集也使用"移动语义"代码的一部分作为其复制代码的一部分。