关于代码的执行时间

Published: by Creative Commons Licence

注意1:系统中有两个 time,一个是 bash 内置的 time 命令,一个是由 time 包提的 /usr/bin/time , 直接执行 time 命令时使用的是 bash 内置的 time。

使用 bash 中的 time 统计一个进程的执行时间如下:

$ time sleep 1

real  0m1.013s
user  0m0.001s
sys   0m0.001s
  • real: 表示 wall time(挂钟时间), 底层使用 gettimeofday() API 来获取时间,它统计的是物理世界中的时间;
  • user: 表示 CPU user time, 底层使用 getrusage() 或者 times() 来获取时间,它统计的是用户态的代码消耗的 CPU 时间,如果代码没有在 CPU 上运行则不会统计在内
  • sys: 和 user 类似,只不过统计程序在内核态运行的时间;

user + sys 表示这个进程(及其子进程)的代码(及其调用的代码)实际在 CPU 上运行的时间,该时间的统计依赖 CPU 硬件,大部分 CPU 硬件都提供了该功能。

系统除了提供以上 API, 还提供了其他的 API 可以用来进行性能参数收集,比如:

  • clock(): 统计当前程序已经执行的 cpu clock ticks(CPU time);
  • clock_gettime(type,*): 根据参数获取不同的时间:

    // file: include/bits/time.h
    /* Identifier for system-wide realtime clock.  */
    # define CLOCK_REALTIME                        0
    /* Monotonic system-wide clock.  */
    # define CLOCK_MONOTONIC                1
    /* High-resolution timer from the CPU.  */
    # define CLOCK_PROCESS_CPUTIME_ID        2
    /* Thread-specific CPU-time clock.  */
    # define CLOCK_THREAD_CPUTIME_ID        3
    /* Monotonic system-wide clock, not adjusted for frequency scaling.  */
    # define CLOCK_MONOTONIC_RAW                4
    /* Identifier for system-wide realtime clock, updated only on ticks.  */
    # define CLOCK_REALTIME_COARSE                5
    /* Monotonic system-wide clock, updated only on ticks.  */
    # define CLOCK_MONOTONIC_COARSE                6
    /* Monotonic system-wide clock that includes time spent in suspension.  */
    # define CLOCK_BOOTTIME                        7
    /* Like CLOCK_REALTIME but also wakes suspended system.  */
    # define CLOCK_REALTIME_ALARM                8
    /* Like CLOCK_BOOTTIME but also wakes suspended system.  */
    # define CLOCK_BOOTTIME_ALARM                9
    /* Like CLOCK_REALTIME but in International Atomic Time.  */
    # define CLOCK_TAI                        11
    

    如果要统计 cpu time, 则推荐使用 CLOCK_MONOTONIC 参数。

    C++11 中的 system_clock::now() 使用gettimeofday()或者std::time(),而steady_clock::now()则使用clock_gettime(CLOCK_MONOTONIC,*);

  • time(): 获取当前的 real time,精度在某些设备上只有 1s,应该避免用于性能统计;
  • getrusage(): 获取资源使用情况;

    struct rusage {
      struct timeval ru_utime; /* user CPU time used */
      struct timeval ru_stime; /* system CPU time used */
      long   ru_maxrss;        /* maximum resident set size */
      long   ru_ixrss;         /* integral shared memory size */
      long   ru_idrss;         /* integral unshared data size */
      long   ru_isrss;         /* integral unshared stack size */
      long   ru_minflt;        /* page reclaims (soft page faults) */
      long   ru_majflt;        /* page faults (hard page faults) */
      long   ru_nswap;         /* swaps */
      long   ru_inblock;       /* block input operations */
      long   ru_oublock;       /* block output operations */
      long   ru_msgsnd;        /* IPC messages sent */
      long   ru_msgrcv;        /* IPC messages received */
      long   ru_nsignals;      /* signals received */
      long   ru_nvcsw;         /* voluntary context switches */
      long   ru_nivcsw;        /* involuntary context switches */
    };
    

    包括 CPU time, 文件系统IO调用次数,上下文切换次数等。

参考资料: