times和getrusage是两个互补的系统级性能统计工具:times专注cpu时间片分配,返回进程及子进程的用户态与内核态累计时间;getrusage提供微秒级时间精度及内存、页错误、上下文切换等多维资源使用详情。

进程执行时间统计不能只看一个“总耗时”,关键要拆开看——用户态时间、内核态时间、实际挂钟时间(wall-clock time)各自反映不同层面的开销。times 和 getrusage 是两个互补性强、无需特权、可嵌入程序内部的系统级工具,适合做细粒度性能归因。
times:专注CPU时间片分配
times() 返回的是进程及其子进程累计消耗的 CPU 时间,单位是 clock tick(通常为 1/100 秒,由 sysconf(_SC_CLK_TCK) 获取)。它不依赖高精度时钟,也不受系统调度抖动干扰,结果稳定可复现。
- 返回结构体 tms 中包含四个字段:tms_utime(本进程用户态时间)、tms_stime(本进程内核态时间)、tms_cutime(已结束子进程的用户态时间)、tms_cstime(已结束子进程的内核态时间)
- 适合用于评估算法本身的 CPU 消耗,比如对比两段计算逻辑在相同负载下的纯 CPU 占用差异
- 注意:它无法区分线程间调度,多线程程序中所有线程的时间会累加到同一进程的 tms_utime/tms_stime 中
getrusage:深入资源使用细节
getrusage(RUSAGE_SELF, &usage) 提供更丰富的运行时画像,不仅有时间维度(ru_utime / ru_stime),还涵盖内存驻留(ru_maxrss)、页错误(ru_majflt)、上下文切换(ru_nvcsw / ru_nivcsw)等关键指标。
- 时间字段以 struct timeval 表示,精度达微秒级,比 times 更精细
- ru_utime 和 ru_stime 分别对应用户空间和内核空间的实际执行时间,二者之和接近真实 CPU 占用,但不等于 wall-clock 时间
- 当 ru_nivcsw(非自愿上下文切换)显著升高,往往说明进程频繁被抢占或等待 I/O;ru_majflt 突增则提示内存访问局部性差或物理内存紧张
两者配合定位性能瓶颈
单靠 wall-clock 时间无法判断慢是因为计算量大、系统调用多,还是被调度器压制。结合 times 和 getrusage 才能分层归因:
- 若 wall-clock 时间远大于 (ru_utime + ru_stime),说明进程大量时间在就绪队列等待或睡眠——查 ru_nivcsw 和系统负载
- 若 ru_utime 高但 ru_stime 也异常高,可能频繁陷入内核(如小数据量反复 read/write、锁竞争导致 futex 调用增多)
- 若 ru_maxrss 持续增长且 ru_majflt 同步上升,大概率存在内存泄漏或低效缓存策略
实操建议
在关键路径前后调用两次 getrusage,差值即为该段代码的资源开销;对长期运行服务,可定期采样并聚合统计趋势。times 更适合作为轻量级周期性监控钩子,嵌入主循环开头结尾即可快速估算 CPU 利用率基线。











