【发布时间】:2021-01-21 17:04:49
【问题描述】:
我很想知道排序 vector <vector<int>> 是否会比排序 vector <array <int, 3>> 慢。 vector 的尺寸是 1000000 x 3,下面是我的驱动代码实现这个:
#include <iostream>
#include <fstream>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
vector <vector<int>> v(1000000, vector <int> (3));
srand(time(nullptr));
for(int i = 0; i < 1000000; ++i){
for(int j = 0; j < 3; ++j){
v[i][j] = rand();
}
}
double start = clock();
sort(v.begin(), v.end());
cout << (clock()-start)/(CLOCKS_PER_SEC/1000) << endl;
return 0;
}
使用 gcc 7.5.0 编译 g++ -O3 sorting_test.cxx,我得到了大约 300 毫秒的运行时间。将 v 声明为 vector <array <int, 3>> 将运行时间减半至大约 149 毫秒。
但是,将v 声明为vector <tuple<int, int, int>> 击败了上述两个选项,平均运行时间约为100 ms。
我可以理解为什么array 选项比vector 选项更快(array 大小是一个常量表达式,与vector 不同),但我不知道为什么tuple 会胜出他们都。有人可以向我解释一下吗?
填写tuple <int, int, int>s的代码是
srand(time(nullptr));
for(int i = 0; i < 1000000; ++i){
get <0> (v[i]) = rand();
get <1> (v[i]) = rand();
get <2> (v[i]) = rand();
}
【问题讨论】:
-
我猜这与
operator <是如何为vector、array和tuple定义的有关。对于vector和array,您需要一个循环。tuple可能使用折叠操作,虽然它具有相同数量的比较,但没有循环开销。 -
显示填充元组向量的代码。此外,使用 srand(0) 获得可重复的结果可能会更好。
-
查看 this 了解什么是折叠表达式。
-
另外,一个向量指向一个动态分配的内存,这对于缓存利用率来说更糟糕。数组向量连续存储所有数据。此外,交换两个向量涉及 48 个字节(在 64 位拱上),而在这种情况下交换数组只有一半。
-
内部交换被执行。在
tuple的情况下,要交换的内存量可能会更低
标签: c++ arrays sorting vector tuples