【如何使用C++的chrono测量代码块的运行时间 Measuring the runtime of a C++ code?】

如何使用C++的chrono测量代码块的运行时间

    • 引子
    • C的方法
    • Cpp的方法
    • 代码
    • 结果
    • 结论

引子

【如何使用C++的chrono测量代码块的运行时间 Measuring the runtime of a C++ code?】_第1张图片
当时在leetcode刷题时,看到这个问题,大家争论了半天未看到一个合理的答案,就想尝试能不能做实验测试一下三种不同的写法的运行时长

C的方法

一开始想到的是陈越姥姥的《数据结构》中使用的方法,使用time.hclock()
【如何使用C++的chrono测量代码块的运行时间 Measuring the runtime of a C++ code?】_第2张图片
但奇怪的是在C++中运行结果全为0.00
偶尔几次结果不为0

Cpp的方法

无奈下,想到了C++有没有属于自己的测试代码运行时长的库文件

一番寻找,在stackoverflow找到了解决办法,使用方法如下

#include 
auto start = std::chrono::steady_clock::now();
// do something
auto finish = std::chrono::steady_clock::now();
double elapsed_seconds = std::chrono::duration_cast<
std::chrono::duration<double> >(finish - start).count();

【如何使用C++的chrono测量代码块的运行时间 Measuring the runtime of a C++ code?】_第3张图片
为了方便测试代码,将那块封装成一个MeasureRuntime()函数,使用回调函数CallBackFun作为参数,分别对三种不同写法对应的test()函数做测试

代码

#include 
#include  
#include 
#include 
#include 
using namespace std;

// 实验数据 
int n = 1;
int num[] = {1, 10, 100, 1000, 10000};
unordered_map<int, int> changes;
vector<vector<int> > grid;

// 估计运行时间 
double MeasureRuntime(void(*CallBackFun)()) {
	auto start = chrono::steady_clock::now();
	CallBackFun();
	auto finish = chrono::steady_clock::now();
	double elapsed_seconds = chrono::duration_cast<
	chrono::duration<double> >(finish - start).count();
	cout << fixed << setprecision(8) << elapsed_seconds << setw(15); 
	/* 	输出格式: 
		fixed 不使用科学计数法 
		setprecision(n) 设置精度,保留n位小数
		setw(m) 对齐,从字符左边第一位开始数
	*/ 
}

// 待测试函数 
void test1() {
	unordered_map<int, int>::iterator it;
	for(it = changes.begin(); it != changes.end(); it++ ) {
		grid[it->first / n][it->first % n] += it->second;
	}
}

void test2() {
	for(auto it:changes) {
		grid[it.first / n][it.first % n] += it.second;	
	}
}

void test3() {
	for(auto &it:changes) {
		grid[it.first / n][it.first % n] += it.second;	
	}
}

// 重置 changes、grid 
void reset() {
	grid.resize(n);
	for(int j=0; j<n; j++) {
		changes[j] = j + 1;
		grid[j].resize(n);
	}
}


int main() {
	cout.setf(ios_base::left); 
	cout << setw(15) << "num" << setw(15) << "test1:it" << setw(15) << 
	"test2:auto" << setw(15) << "test3:auto &" << setw(15) << endl;
	for(int i=0; i<5; i++) {
		n = num[i];
		cout << n << setw(15);
		reset();
		MeasureRuntime(test1); 
		MeasureRuntime(test2); 
		MeasureRuntime(test3);
		cout << endl;
	}
	return 0;
}

结果

/*
num            test1:it       test2:auto     test3:auto &
1              0.00000030     0.00000140     0.00000050
10             0.00000090     0.00000080     0.00000080
100            0.00000600     0.00000420     0.00001770
1000           0.00005470     0.00003350     0.00003490
10000          0.00069710     0.00038380     0.00068700

num            test1:it       test2:auto     test3:auto &
1              0.00000040     0.00000050     0.00000040
10             0.00000080     0.00000080     0.00000080
100            0.00000570     0.00000410     0.00000450
1000           0.00005710     0.00003540     0.00003500
10000          0.00053880     0.00036460     0.00038480

num            test1:it       test2:auto     test3:auto &
1              0.00000030     0.00000060     0.00000060
10             0.00000090     0.00000090     0.00000080
100            0.00000600     0.00000390     0.00000410
1000           0.00005920     0.00003690     0.00005330
10000          0.00055230     0.00035290     0.00032940
100000         terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
*/ 

/*
the for loop can't sit outside the function 
*/ 

结论

可以发现,处于不同的数量级,三种写法的性能是波动的;
总体来说,
当数量级较大时,性能上:auto & > auto > iterator
当数量级较小时,性能上:iterator > auto & > auto

Reference
[1]: 陈越姥姥《数据结构》
[2]: Measuring the runtime of a C++ code?
[3]: C++setw()函数
[4]: C++ 中的 cout.setf()函数

你可能感兴趣的:(c++)