被忽视的time命令

如果要选 Linux 下最容易被忽视的命令,time 应该算一个。简单来说,它是一个用来计算命令运行时间的工具,之所以说它容易被忽视,一方面很多人根本不知道 time 的存在,而是习惯在命令启动前后记录两个时间戳,然后手动计算命令运行时间;另一方面很多人虽然知道 time 的存在,但是却并没有真正理解它的含义。

下面让我们通过若干例子来理解 time 的真正含义:

shell> time ls

real	0m0.003s
user	0m0.001s
sys	0m0.002s

大概意思是 ls 命令运行花了 0.003 秒,其中用户态花了 0.001 秒,内核态花了 0.002 秒,看上去似乎「real = user + sys」?此等式是否成立,在回答这个问题之前我们不妨看看 real、user、sys 的确切含义,如下定义源自 Stackoverflow

  • Real is wall clock time – time from start to finish of the call. This is all elapsed time including time slices used by other processes and time the process spends blocked (for example if it is waiting for I/O to complete).
  • User is the amount of CPU time spent in user-mode code (outside the kernel) within the process. This is only actual CPU time used in executing the process. Other processes and time the process spends blocked do not count towards this figure.
  • Sys is the amount of CPU time spent in the kernel within the process. This means executing CPU time spent in system calls within the kernel, as opposed to library code, which is still running in user-space. Like ‘user’, this is only CPU time used by the process.

总的来说,real 是我们直观感受到的消耗的时间,如果命令运行时被堵塞了,那么堵塞时间也是被统计在内的, user 统计在用户态态模式下消耗的 CPU 时间,如果命令运行时被堵塞了,那么堵塞时间并不被统计在内,sys 统计在内核态模式下消耗的 CPU 时间,如果命令运行时被堵塞了,那么堵塞时间并不被统计在内。

看上去是否统计堵塞时间是区分 real 和 user、sys 的关键,看看下面这个 sleep 例子:

shell> time sleep 1

real	0m1.002s
user	0m0.001s
sys	0m0.001s

那么除了堵塞时间,还有别的关键点么,让我们再看看下面两个例子:

shell> time find /etc -type f | xargs -n1 -I{} cat {} > /dev/null

real	0m2.050s
user	0m0.626s
sys	0m1.533s

shell> time find /etc -type f | xargs -n1 -I{} -P2 cat {} > /dev/null

real	0m1.079s
user	0m0.681s
sys	0m1.486s

前后两个例子的区别在于后者在使用 xargs 的时候通过「-P」选项激活了多进程,换句话说,后者可以同时用到多个 CPU。

了解了相关知识之后,我们通过 real、user、sys 的大小就可以判断程序的行为:

  • 如果 real 远远大于 user + sys,那么说明程序可能有严重的堵塞问题。
  • 如果 real 基本等于 user + sys,那么说明程序可能没有用到多 CPU 能力,
  • 如果 real 远远小于 user + sys,那么说明程序可能用到了多 CPU 能力。

怎么样?看似简单的 time 命令,是不是远比你想的要复杂得多!

被忽视的time命令》上有4个想法

  1. 一直以为time是用做查看时间的,其实date才是,其实这些简单的命令各种参数用好、记好不容易

发表评论

电子邮件地址不会被公开。 必填项已用*标注