最常用且可靠的性能评估方案是/usr/bin/time -v,它能准确获取整个进程(含子进程)的挂钟时间和最大物理内存占用(kb),而clock_gettime(clock_monotonic)适用于纳秒级函数级cpu耗时测量。

直接用 /usr/bin/time -v 就能拿到完整耗时和内存峰值,比自己写计时逻辑快、准、不干扰程序行为。自己在代码里插桩测时间,只在需要微秒级精度或分析某段内部逻辑时才值得做。
用 /usr/bin/time -v 看真实耗时和最大内存
这是最常用也最可靠的方案,尤其适合评估整个可执行文件的性能表现。
-
/usr/bin/time是 GNU time,不是 shell 内置的time;后者不支持-v,输出也极简 -
-v输出里重点关注两项:Elapsed (wall clock) time(挂钟时间)和Maximum resident set size(最大物理内存占用,单位 KB) - 如果提示
command not found,Debian/Ubuntu 系运行sudo apt install time,RHEL/CentOS 用sudo yum install time - 它会统计整个进程树,包括 fork 出的子进程——这对有子进程的程序(如调用
system()或popen())很关键
在 C 代码里用 clock_gettime(CLOCK_MONOTONIC, ...)
要测某段函数或循环的精确开销,且要求纳秒级、不受系统时间跳变影响,就用 clock_gettime。
- 必须包含
#include <time.h></time.h>,链接时无需额外库(glibc 自带) - 优先选
CLOCK_MONOTONIC:从系统启动开始计,不随date或 NTP 调整跳变,适合性能测量 - 别用
CLOCK_REALTIME:它会被手动改系统时间或 NTP 校正拉扯,两次差值可能为负 - 示例片段:
struct timespec start, end; clock_gettime(CLOCK_MONOTONIC, &start); // your code here clock_gettime(CLOCK_MONOTONIC, &end); long long ns = (end.tv_sec - start.tv_sec) * 1000000000LL + (end.tv_nsec - start.tv_nsec);
gettimeofday() 还能用吗?
能,但不推荐新代码使用。
-
gettimeofday()精度到微秒,但已被标记为 legacy;POSIX.1-2008 推荐用clock_gettime(CLOCK_REALTIME, ...)替代 - 它的
struct timezone *参数已废弃,传NULL即可 - 实际误差比
clock_gettime大:部分内核实现里它底层仍走 jiffies,受 HZ 影响,在低负载下可能“卡”在同一个值上多次 - 如果你维护老代码且只需求毫秒级,它仍稳定;但新项目请直接上
clock_gettime
为什么 clock() 不适合测总耗时?
clock() 返回的是 CPU 时间,不是挂钟时间,容易严重误导。
- 它只累加当前进程在用户态 + 内核态实际占用 CPU 的时间,sleep、I/O 等待期间完全不计
- 比如一段代码
sleep(2); do_work();,clock()可能只报几毫秒,而真实耗时是 2 秒多 -
CLOCKS_PER_SEC在 glibc 中固定为 1000000,但实际分辨率取决于内核配置,未必真达微秒 - 仅适用于纯计算密集型任务的 CPU 时间估算,比如比较两个算法的理论吞吐
真正难的不是选哪个 API,而是理解你到底想测什么:是用户感知的等待时间(用 /usr/bin/time),还是某段纯计算的 CPU 开销(用 clock_gettime(CLOCK_PROCESS_CPUTIME_ID)),还是跨线程协作中的逻辑延迟(得结合 CLOCK_THREAD_CPUTIME_ID 和同步点)。搞混这三者,再准的数字也没意义。











