C语言程序函数计时仅显示三位小数的原因排查求助
C语言排序算法计时仅显示三位小数的问题分析
问题描述
我在编写测试不同排序算法的C程序时,发现计时输出只能显示三位小数(如CSV中0.001000、0.002000这类格式),即使使用%f格式输出也是如此。使用环境为Windows 11系统、AMD Ryzen 5处理器,曾怀疑是硬件或系统配置导致。
相关代码片段
code.c
// insertion sort test time_t t = 0; t = clock(); insertion(arr, n); t = clock() - t; double time_taken = ((double)t)/CLOCKS_PER_SEC; // in seconds printf("insertion() took %f seconds to execute\n", time_taken); fprintf(fp, "%f,", time_taken); fflush(fp);
data.csv
0.001000,0.000000,0.000000,0.001000,0.000000 0.002000,0.000000,0.000000,0.002000,0.000000 0.005000,0.000000,0.000000,0.005000,0.000000 0.008000,0.001000,0.000000,0.008000,0.000000 0.004000,0.000000,0.000000,0.021000,0.000000 0.011000,0.000000,0.000000,0.024000,0.001000 0.008000,0.016000,0.000000,0.025000,0.000000 0.031000,0.001000,0.001000,0.029000,0.000000 0.041000,0.001000,0.000000,0.033000,0.000000 0.060000,0.001000,0.001000,0.051000,0.001000 0.062000,0.001000,0.000000,0.059000,0.001000 0.074000,0.002000,0.001000,0.068000,0.000000 0.085000,0.002000,0.001000,0.080000,0.000000
原因分析
这不是硬件或系统配置的问题,而是clock()函数的精度限制:
- Windows平台下,
CLOCKS_PER_SEC被定义为1000,意味着clock()的计时精度是毫秒级(1/1000秒)。 - 计算出的
time_taken最小单位就是0.001秒,所以输出只会以0.001的整数倍显示,看起来只有三位有效小数。
解决方案
1. 使用高精度Windows API计时
改用QueryPerformanceCounter和QueryPerformanceFrequency,这两个函数可以提供微秒甚至纳秒级的精度,完全满足细粒度计时需求:
#include <windows.h> // 高精度计时示例 LARGE_INTEGER freq, start, end; QueryPerformanceFrequency(&freq); // 获取计数器频率 QueryPerformanceCounter(&start); // 记录开始时间 insertion(arr, n); // 执行排序函数 QueryPerformanceCounter(&end); // 记录结束时间 double time_taken = (double)(end.QuadPart - start.QuadPart) / freq.QuadPart; printf("insertion() took %.6f seconds to execute\n", time_taken); fprintf(fp, "%.6f,", time_taken); fflush(fp);
2. 多次运行取平均值(兼容原代码)
如果不想修改计时逻辑,可以多次运行排序函数,把总时间除以运行次数,放大时间基数以获得更精确的单次时间:
int runs = 1000; time_t t = clock(); for (int i = 0; i < runs; i++) { insertion(arr, n); } t = clock() - t; double time_taken = ((double)t)/CLOCKS_PER_SEC / runs; // 单次运行时间 printf("insertion() took %.6f seconds to execute\n", time_taken); fprintf(fp, "%.6f,", time_taken); fflush(fp);
内容的提问来源于stack exchange,提问作者Grovetender
相关产品推荐
相关产品推荐

