【发布时间】:2017-04-08 09:11:54
【问题描述】:
这是Efficient way to return a std::vector in c++的一个扩展问题
#include <cstdio>
#include <vector>
#include <chrono>
std::vector<int> func1() {
std::vector<int> v;
v.reserve(1e6);
for (int i = 0; i < 1e6; i++) v.emplace_back(i);
return v;
}
std::vector<int> func2() {
std::vector<int> v;
v.reserve(1e6);
for (int i = 0; i < 1e6; i++) v.emplace_back(i);
return std::move(v);
}
int main() {
auto start1 = std::chrono::steady_clock::now();
std::vector<int> v1 = func1();
auto end1 = std::chrono::steady_clock::now();
printf("%d\n", std::chrono::duration_cast<std::chrono::nanoseconds>(end1-start1).count());
auto start2 = std::chrono::steady_clock::now();
std::vector<int> v2 = func2();
auto end2 = std::chrono::steady_clock::now();
printf("%d\n", std::chrono::duration_cast<std::chrono::nanoseconds>(end2-start2).count());
/*
auto start3 = std::chrono::steady_clock::now();
std::vector<int> v3 = v2;
auto end3 = std::chrono::steady_clock::now();
printf("%d\n", std::chrono::duration_cast<std::chrono::nanoseconds>(end3-start3).count());
*/
return 0;
}
在方法 2 中,我明确告诉编译器我要移动而不是复制向量,但多次运行代码显示方法 1 有时实际上优于方法 2,即使方法 2 获胜,也差不了多少.
方法 3 始终是最好的。当我必须从函数返回时如何模拟方法 3? (不,我不能通过引用)
使用 gcc 6.1.0
【问题讨论】:
-
a) 防止最微小的不需要的编译器优化。作为编译器,我会删除例如。 v3,所以第三个是最快的不是你想知道的。
-
请注意,您的基准测试存在缺陷:您也在计时插入向量,包括 重新分配。
-
并且编译器也可以对
func1使用移动,它不必复制。 -
func2的 Clang 警告:警告:在返回语句中移动本地对象可防止复制省略 [-Wpessimizing-move]