问题描述
我很好奇,看看对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>
的代码是
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<
的{{1}}与array
之间的核心区别:https://godbolt.org/z/h1Y33e
本质上,在元组版本中,您具有3个元素的固定比较,而在数组版本中,您具有循环。
尽管令我惊讶的是编译器没有展开循环。
编辑:好像clang确实将它们优化为两个非循环代码:https://godbolt.org/z/cMExTb(我没有完全读懂它,但是我只看到向前跳转)