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

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

引子

在这里插入图片描述
当时在leetcode刷题时,看到这个问题,大家争论了半天未看到一个合理的答案,就想尝试能不能做实验测试一下三种不同的写法的运行时长

C的方法

一开始想到的是陈越姥姥的《数据结构》中使用的方法,使用time.hclock()
在这里插入图片描述
但奇怪的是在C++中运行结果全为0.00
偶尔几次结果不为0

Cpp的方法

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

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

#include <chrono>
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();

在这里插入图片描述
为了方便测试代码,将那块封装成一个MeasureRuntime()函数,使用回调函数CallBackFun作为参数,分别对三种不同写法对应的test()函数做测试

代码

#include <iostream>
#include <unordered_map> 
#include <vector>
#include <chrono>
#include <iomanip>
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++中,使用 `<chrono>` 库来测量函数运行时间是一个常见的做法。这个库提供了精确的时间测量功能,可以用来计算代码段的执行时间。下面是一个基本的例子来说明如何使用 `<chrono>` 来测量函数的运行时间: ```cpp #include <iostream> #include <chrono> void functionToMeasure() { // 这里是需要测量运行时间的代码 } int main() { // 记录开始时间点 auto start = std::chrono::high_resolution_clock::now(); // 运行需要测量的函数 functionToMeasure(); // 记录结束时间点 auto end = std::chrono::high_resolution_clock::now(); // 计算时间间隔 auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start); // 输出结果 std::cout << "Function took " << duration.count() << " microseconds." << std::endl; return 0; } ``` 如果你在使用 `<chrono>` 库时报错,可能的原因有以下几种: 1. **缺少必要的头文件**:确保你的代码中包含了 `<chrono>` 头文件。 2. **编译器不支持C++11或更高版本**:`<chrono>` 是C++11标准库的一部分,如果你的编译器不支持C++11或更高版本,那么可能会报错。确保你的编译器设置为支持C++11或以上。 3. **命名空间问题**:如果你没有使用 `std::` 前缀,确保你的代码中包含了 `using namespace std;` 或者在 `chrono` 相关类型和函数前加上 `std::` 前缀。 4. **其他编译器错误**:仔细检查报错信息,它通常会告诉你错误的具体位置和原因。常见的编译错误可能包括语法错误、类型不匹配等。 如果你仍然不能确定错误的原因,可以提供具体的报错信息,这样可以更准确地帮助你解决问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值