Contents
  1. 1. 前言
  2. 2. 正文
  3. 3. 总结

前言

在之前的文章 EarlGrey 源码阅读(二) 中整理了 iOS 中几种常见的测量程序运行时间的方法,末尾提到了希望有更科学的测量方法——可以计算当前进程分别在用户态和内核态占用 CPU 多长时间。使用 times 或者 getrusage 这两个操作系统提供的方法可以办到了。

正文

times 方法提供一个结构体参数,查询的结果放里面。这个结构体包含当前进程在用户态、内核态占用的 CPU 时间,以及其所有子进程对应的时间。函数的返回值是真实世界的时间值,就是包含了别的进程的时间的意思。精确到 0.01 s。

struct tms {
    clock_t	tms_utime;	/* [XSI] User CPU time */
    clock_t	tms_stime;	/* [XSI] System CPU time */
    clock_t	tms_cutime;	/* [XSI] Terminated children user CPU time */
    clock_t	tms_cstime;	/* [XSI] Terminated children System CPU time */
};

getrusage 功能类似,它还提供了一些别的信息,时间只是一部分。它要更精确些,可以达到 us 级别。

void doWork(void) {
    for (int i = 0; i < 10000; i++) {
        printf("A\n");
    }
}

int test(void) {
    
    struct tms start_tms, end_tms;
    clock_t start, end;
    long clktck = sysconf(_SC_CLK_TCK);
    
    struct rusage start_usage, end_usage;
    
    getrusage(RUSAGE_SELF, &start_usage);
    start = times(&start_tms);
    
    doWork();
    
    getrusage(RUSAGE_SELF, &end_usage);
    end = times(&end_tms);
    
    printf("real time is %f\n", (end - start) / (double)clktck);
    printf("user time is %f\n", (end_tms.tms_utime - start_tms.tms_utime) / (double)clktck);
    printf("sys time is %f\n", (end_tms.tms_stime - start_tms.tms_stime) / (double)clktck);
    
    printf("getrusage user time is %f\n", (end_usage.ru_utime.tv_usec - start_usage.ru_utime.tv_usec) / (double)1000000);
    printf("getrusage sys time is %f\n", (end_usage.ru_stime.tv_usec - start_usage.ru_stime.tv_usec) / (double)1000000);
    
    return 0;
}

统计出来的结果:

real time is 0.040000
user time is 0.010000
sys time is 0.010000

getrusage user time is 0.009294
getrusage sys time is 0.010072

用 times 得到的结果是当前进程用了 0.02s,真实世界流逝了 0.04s,那还有 0.02s 就是进程调度的时候调度给别的进程了。
用 getrusage 得到 us 级别的统计。

总结

关于时间计算这块儿几个方法

  • NSDate 单位 秒

  • CFAbsoluteTimeGetCurrent 单位 秒

  • times 单位 百分之一秒(但是可以只计算当前进程时间也可以计算客观时间,以及时间在用户态、内核态的分布)

  • getrusage 单位 微秒(只计算当前进程时间以及在用户态、内核态的分布)

  • mach_absolute_time 单位 纳秒

Contents
  1. 1. 前言
  2. 2. 正文
  3. 3. 总结