我编写了一个小基准测试程序来检查访问存储在向量中的数据的一些方法。我使用 tww 嵌套 for 循环来面对 A)为第一个循环的每次迭代创建对向量对象的引用,并在第二个 for 循环中使用该引用 B)创建一个指针,在该指针中存储对第一个循环的每次迭代的向量对象,并在第二个 for 循环中使用该指针 C) 使用 [] 运算符直接访问向量对象 D) 在第一个循环中使用 auto&
这样一对嵌套的 for 循环本身与计时函数一起嵌套在另一个循环中。多次运行测试,for 循环从 0 到 100,我得到所有这些方法的相同计时结果,始终在 0.150 秒左右,波动为 0.02%。
我的问题是:
1)我的测试正确吗?
2)我错过了一些优化/不同的方法,哪个可能更快?
这是我的代码
#include <iostream>
#include <chrono>
#include <ratio>
#include <ctime>
#include <vector>
using namespace std;
using namespace std::chrono;
struct my_struct{
vector<float> data;
my_struct(int N, float x){
for(int i=0;i<N;i++){
data.push_back(cos(x+i));
}
}
void work(){
for(int i=0;i<data.size();i++){
data[i]=data[i]*data[i];
}
}
};
int main(){
int N=100;
vector<my_struct> stuff;
for(int k=0; k<N; ++k){
stuff.push_back( my_struct(100,sin(k)) );
}
vector<duration<double>> results_t1,results_t2,results_t3,results_t4;
high_resolution_clock::time_point t1 = high_resolution_clock::now();
for(int k=0; k<N; ++k){
int which=0; //this is used to choose what method of access will be used
switch(which){
case 0:{ //pointer
my_struct * thing=NULL;
for( int i=0; i<N;++i){
high_resolution_clock::time_point t2 = high_resolution_clock::now();
for( int j=0; j<N;++j){
thing =&stuff[j];
for( int jj=0; jj<N;++jj)
thing->work();
}
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
results_t1.push_back(time_span);
t1=t2;
}
break;
}
case 1:{ //direct access
for( int i=0; i<N;++i){
high_resolution_clock::time_point t2 = high_resolution_clock::now();
for( int j=0; j<N;++j){
for( int jj=0; jj<N;++jj)
stuff[j].work();
}
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
results_t2.push_back(time_span);
t1=t2;
}
break;
}
case 2:{ //auto reference
for( int i=0; i<N;++i){
high_resolution_clock::time_point t2 = high_resolution_clock::now();
for( auto& temp : stuff){
for( int jj=0; jj<N;++jj)
temp.work();
}
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
results_t3.push_back(time_span);
t1=t2;
}
break;
}
case 3:{ //reference
for( int i=0; i<N;++i){
high_resolution_clock::time_point t2 = high_resolution_clock::now();
for( int j=0; j<N;++j){
my_struct & temp =stuff[j];
for( int jj=0; jj<N;++jj)
temp.work();
}
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
results_t4.push_back(time_span);
t1=t2;
}
break;
}
}
}
double temp=0;
for(auto& t : results_t1){
temp+=t.count();
}
temp=temp/N;
std::cout << "pointer " << temp << " seconds.";
std::cout << std::endl;
temp=0.0;
for(auto& t : results_t2){
temp+=t.count();
}
temp=temp/N;
std::cout << "direct " << temp << " seconds.";
std::cout << std::endl;
temp=0.0;
for(auto& t : results_t3){
temp+=t.count();
}
temp=temp/N;
std::cout << "auto reference " << temp << " seconds.";
std::cout << std::endl;
temp=0.0;
for(auto& t : results_t4){
temp+=t.count();
}
temp=temp/N;
std::cout << "reference " << temp << " seconds.";
std::cout << std::endl;
cin.get();
return 0;
}