Windows及WSL2 Ubuntu下C++测量排序算法CPU执行时间方案
精确测量排序算法的进程CPU时间方案
Linux/WSL2 Ubuntu 环境实现
在WSL2的Ubuntu环境下,优先使用POSIX标准的进程CPU时间测量接口,完全不受系统其他进程干扰,且支持长时间计时:
方案1:clock_gettime(推荐)
使用CLOCK_PROCESS_CPUTIME_ID时钟,专门统计当前进程的总CPU时间(用户态+内核态),精度可达纳秒级,且时间戳为64位,无溢出风险。
#include <time.h> // 记录起始时间 struct timespec start, end; clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); // 执行你的快速排序算法 your_quicksort_function(data, size); // 记录结束时间 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end); // 计算CPU时间(秒) double cpu_time_sec = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1000000000.0;
方案2:getrusage
可以分开统计用户态和内核态的CPU时间,适合需要更细致分析的场景:
#include <sys/resource.h> struct rusage start_ru, end_ru; getrusage(RUSAGE_SELF, &start_ru); // 执行排序 your_quicksort_function(data, size); getrusage(RUSAGE_SELF, &end_ru); // 计算用户态CPU时间(毫秒) long user_ms = (end_ru.ru_utime.tv_sec - start_ru.ru_utime.tv_sec) * 1000 + (end_ru.ru_utime.tv_usec - start_ru.ru_utime.tv_usec) / 1000; // 计算内核态CPU时间(毫秒) long sys_ms = (end_ru.ru_stime.tv_sec - start_ru.ru_stime.tv_sec) * 1000 + (end_ru.ru_stime.tv_usec - start_ru.ru_stime.tv_usec) / 1000; double total_cpu_sec = (user_ms + sys_ms) / 1000.0;
Windows 原生环境实现
Windows下std::clock返回的是挂钟时间(包含其他进程占用的时间),需使用Windows API GetProcessTimes获取进程专属的CPU时间:
#include <windows.h> FILETIME create_time, exit_time, kernel_time, user_time; GetProcessTimes(GetCurrentProcess(), &create_time, &exit_time, &kernel_time, &user_time); // 转换起始时间为64位整数(单位:100纳秒) ULARGE_INTEGER start_kernel, start_user; start_kernel.LowPart = kernel_time.dwLowDateTime; start_kernel.HighPart = kernel_time.dwHighDateTime; start_user.LowPart = user_time.dwLowDateTime; start_user.HighPart = user_time.dwHighDateTime; // 执行排序 your_quicksort_function(data, size); // 记录结束时间并转换 GetProcessTimes(GetCurrentProcess(), &create_time, &exit_time, &kernel_time, &user_time); ULARGE_INTEGER end_kernel, end_user; end_kernel.LowPart = kernel_time.dwLowDateTime; end_kernel.HighPart = kernel_time.dwHighDateTime; end_user.LowPart = user_time.dwLowDateTime; end_user.HighPart = user_time.dwHighDateTime; // 计算总CPU时间(秒) double cpu_time_sec = ( (end_kernel.QuadPart - start_kernel.QuadPart) + (end_user.QuadPart - start_user.QuadPart) ) / 10000000.0;
该API返回的时间为64位,完全不会出现36分钟溢出的问题,且仅统计当前进程的CPU占用时间。
长时间计时的关键注意事项
- 彻底放弃
std::clock:多数系统中clock_t为32位类型,当CLOCKS_PER_SEC为1e6时,最多只能统计约71分钟的时间,部分系统甚至更短,无法满足你的测试需求。 - 上述所有方案均使用64位时间表示,即使算法运行数小时也不会出现溢出问题。
测试优化建议
- 对同一规模的测试数据,重复运行排序算法5-10次,取CPU时间的平均值,减少单次运行的偶然误差。
- 确保两种快速排序算法使用完全相同的输入数据集,保证对比的公平性。
内容的提问来源于stack exchange,提问作者Hrishabh Nayal
相关产品推荐
相关产品推荐

