如何利用std::chrono实现<1秒的精确计时及多单位精准展示?
问题描述
想要计算程序中算法的运行时间,并以小时、分钟、秒、毫秒等不同单位展示,现有实现如下:
auto start = high_resolution_clock::now(); myFunction(); auto stop = high_resolution_clock::now(); auto duration = duration_cast<seconds>(stop - start); const auto hrs = duration_cast<hours>(duration); const auto mins = duration_cast<minutes>(duration - hrs); const auto secs = duration_cast<seconds>(duration - hrs - mins); const auto ms = duration_cast<milliseconds>(duration - hrs - mins - secs); std::cout << "Time needed: "<<hrs.count()<<" hours "<<mins.count()<<" mins "<<secs.count()<<" secs " <<ms.count()<<" milisecs "
期望输出示例:
Time needed: 0 hours 1 mins 30 seconds 2400miliseconds
但实际运行存在问题:
- 运行时间<1秒时,所有值(包括毫秒)都显示为0;
- 运行时间≥1秒时,无法显示精确时间,比如实际非整1秒,却输出:
Time needed: 0 hours 0 mins 1 seconds 1000miliseconds
该实现因先将时间差转换为整秒,丢失了高精度信息,导致无法体现真实运行时间,需要解决此问题,同时希望了解除std::chrono之外的其他可行方法。
解决方法
一、修正std::chrono的实现
问题核心是过早将时间差转换为秒级,丢失了毫秒及以下的精度。正确的做法是保留原始的高精度时间差,再依次转换为不同单位:
#include <chrono> #include <iostream> #include <thread> void myFunction() { // 示例函数,模拟耗时操作 std::this_thread::sleep_for(std::chrono::milliseconds(1500)); } int main() { auto start = std::chrono::high_resolution_clock::now(); myFunction(); auto stop = std::chrono::high_resolution_clock::now(); // 保留原始高精度时间差,不提前转换为秒 auto duration = stop - start; // 从大到小依次计算各单位的时间,每次减去已计算的部分 const auto hrs = std::chrono::duration_cast<std::chrono::hours>(duration); duration -= hrs; const auto mins = std::chrono::duration_cast<std::chrono::minutes>(duration); duration -= mins; const auto secs = std::chrono::duration_cast<std::chrono::seconds>(duration); duration -= secs; const auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(duration); std::cout << "Time needed: " << hrs.count() << " hours " << mins.count() << " mins " << secs.count() << " seconds " << ms.count() << " milliseconds\n"; return 0; }
这段代码会输出类似:Time needed: 0 hours 0 mins 1 seconds 500 milliseconds,完全保留了时间精度。如果需要显示微秒或纳秒,只需要继续添加对应的转换步骤即可:
duration -= ms; const auto us = std::chrono::duration_cast<std::chrono::microseconds>(duration); // 输出时加上us.count() << " microseconds"
二、其他可行方法
1. C标准库的clock()函数
适用于测量CPU时间(进程占用的CPU时间,而非实际流逝时间),单位为时钟周期,需要转换为秒:
#include <time.h> #include <iostream> #include <thread> void myFunction() { std::this_thread::sleep_for(std::chrono::milliseconds(1500)); } int main() { clock_t start = clock(); myFunction(); clock_t end = clock(); double cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC; // 转换为毫秒、微秒 long ms = (long)(cpu_time_used * 1000); long us = (long)(cpu_time_used * 1000000); std::cout << "CPU time used: " << cpu_time_used << " seconds (" << ms << " ms, " << us << " us)\n"; return 0; }
注意:clock()测量的是CPU时间,如果程序处于休眠状态,这部分时间不会被计入。
2. Linux/Unix下的gettimeofday()
可以获取当前的墙上时间(实际流逝时间),精度到微秒:
#include <sys/time.h> #include <iostream> #include <thread> void myFunction() { std::this_thread::sleep_for(std::chrono::milliseconds(1500)); } int main() { struct timeval start, end; gettimeofday(&start, nullptr); myFunction(); gettimeofday(&end, nullptr); long seconds = end.tv_sec - start.tv_sec; long microseconds = end.tv_usec - start.tv_usec; if (microseconds < 0) { seconds--; microseconds += 1000000; } long ms = seconds * 1000 + microseconds / 1000; std::cout << "Time needed: " << seconds << " seconds " << ms % 1000 << " milliseconds " << microseconds % 1000 << " microseconds\n"; return 0; }
3. Windows下的QueryPerformanceCounter()
这是Windows平台的高精度计时API,精度可达纳秒级:
#include <windows.h> #include <iostream> void myFunction() { Sleep(1500); } int main() { LARGE_INTEGER start, end, freq; QueryPerformanceFrequency(&freq); // 获取计数器频率 QueryPerformanceCounter(&start); myFunction(); QueryPerformanceCounter(&end); // 计算耗时,转换为秒、毫秒、微秒 double elapsed = (double)(end.QuadPart - start.QuadPart) / freq.QuadPart; long seconds = (long)elapsed; long ms = (long)(elapsed * 1000) % 1000; long us = (long)(elapsed * 1000000) % 1000; std::cout << "Time needed: " << seconds << " seconds " << ms << " milliseconds " << us << " microseconds\n"; return 0; }
内容的提问来源于stack exchange,提问作者JACK1ETO
相关产品推荐
相关产品推荐

