在C++里,统计程序运行时间是性能分析工作的重要组成部分。下面为总结几种常用的计时方法及其使用场景。
1. C++11标准库中的std::chrono
(高精度计时)
头文件:#include <chrono>
使用场景:适合对精度要求极高的场景,像算法性能测试这类场景就很适用。
示例代码:
#include <iostream>
#include <chrono>
int main() {
auto start = std::chrono::high_resolution_clock::now();
// 待计时的代码
for (int i = 0; i < 1000; ++i) {
// 执行一些操作
}
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
std::cout << "程序运行时间: " << duration.count() << " 微秒" << std::endl;
return 0;
}
时间单位:
nanoseconds
(纳秒)microseconds
(微秒)milliseconds
(毫秒)seconds
(秒)
2. std::clock()
(传统C风格计时)
头文件:#include <ctime>
使用场景:适用于统计CPU时间,不过精度相对较低。
示例代码:
#include <iostream>
#include <ctime>
int main() {
clock_t start = clock();
// 待计时的代码
for (int i = 0; i < 1000; ++i) {
// 执行一些操作
}
clock_t end = clock();
double duration = (double)(end - start) / CLOCKS_PER_SEC;
std::cout << "程序运行时间: " << duration << " 秒" << std::endl;
return 0;
}
注意事项:
- 该方法统计的是CPU时间,若程序中有I/O操作或多线程操作,统计结果可能会和实际耗时有偏差。
3. gettimeofday()
(Unix/Linux系统调用)
头文件:#include <sys/time.h>
使用场景:适用于Unix/Linux系统,能提供微秒级别的精度。
示例代码:
#include <iostream>
#include <sys/time.h>
int main() {
struct timeval start, end;
gettimeofday(&start, nullptr);
// 待计时的代码
for (int i = 0; i < 1000; ++i) {
// 执行一些操作
}
gettimeofday(&end, nullptr);
long seconds = end.tv_sec - start.tv_sec;
long microseconds = end.tv_usec - start.tv_usec;
double duration = seconds + microseconds * 1e-6;
std::cout << "程序运行时间: " << duration << " 秒" << std::endl;
return 0;
}
4. Windows系统专用的QueryPerformanceCounter
头文件:#include <windows.h>
使用场景:仅适用于Windows系统,可提供高精度的计时功能。
示例代码:
#include <iostream>
#include <windows.h>
int main() {
LARGE_INTEGER frequency, start, end;
QueryPerformanceFrequency(&frequency);
QueryPerformanceCounter(&start);
// 待计时的代码
for (int i = 0; i < 1000; ++i) {
// 执行一些操作
}
QueryPerformanceCounter(&end);
double duration = (double)(end.QuadPart - start.QuadPart) / frequency.QuadPart;
std::cout << "程序运行时间: " << duration << " 秒" << std::endl;
return 0;
}
5. 函数封装与RAII技术(自动计时)
实现方式:借助构造函数和析构函数来自动完成计时工作。
示例代码:
#include <iostream>
#include <chrono>
class Timer {
private:
std::chrono::high_resolution_clock::time_point start_time;
std::string name;
public:
Timer(const std::string& timerName) : name(timerName) {
start_time = std::chrono::high_resolution_clock::now();
}
~Timer() {
auto end_time = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
std::cout << name << " 运行时间: " << duration.count() << " 毫秒" << std::endl;
}
};
void someFunction() {
Timer t("函数计时");
// 待计时的代码
for (int i = 0; i < 1000; ++i) {
// 执行一些操作
}
}
int main() {
someFunction();
return 0;
}
方法对比与建议
方法 | 精度 | 跨平台性 | 推荐场景 |
---|---|---|---|
std::chrono | 纳秒级 | 是 | 高精度计时(C++11及以上) |
std::clock() | 毫秒级 | 是 | 统计CPU时间 |
gettimeofday() | 微秒级 | Unix/Linux | 系统级高精度计时 |
QueryPerformanceCounter | 纳秒级 | Windows | Windows系统高精度计时 |
RAII计时器 | 纳秒级 | 是 | 自动统计函数或代码块的执行时间 |
注意事项
- 若要进行性能测试,需多次运行取平均值,以此减少系统负载波动带来的影响。
- 要留意编译器优化可能对计时结果产生的干扰,必要时可禁用优化(如使用
-O0
选项)。 - 统计多线程程序时,要明确是统计总CPU时间还是实际运行时间。