在分析应用程序的效率或比较不同的算法时,其执行时间非常重要。

9.3.1 实战演练

(1) time命令可以测量出应用程序的执行时间

  1. $ time APPLICATION

time命令会执行APPLICATION。当APPLICATION执行完毕后,time命令将其real时间、sys时间以及user时间输出到stderr中,将APPLICATION的正常输出发送到stdout

  1. $ time ls
  2. archive.tar.gz golang output.txt sample1.txt temp.txt variables.sh welcome.txt
  3. echo if.sh out.txt sample2.txt tools vitest
  4. else input.txt printf.sh showArgs.sh umq vitest.tar
  5. real 0m0.004s
  6. user 0m0.003s
  7. sys 0m0.001s

time命令的可执行二进制文件位于/usr/bin/time,另外还有一个bash shell的内建命令也叫作time。当执行time时,默认调用的是shell的内建命令。内建的time命令选项有限。如果需要使用额外的功能,应该使用可执行文件time的绝对路径(/usr/bin/time)。

(2) 选项-o可以将相关的时间统计信息写入文件

  1. $ yum install time -y
  2. $ /usr/bin/time -o output.txt COMMAND
  1. [root@dev workspace]# ls
  2. archive.tar.gz golang output.txt sample1.txt temp.txt variables.sh welcome.txt
  3. echo if.sh out.txt sample2.txt tools vitest
  4. else input.txt printf.sh showArgs.sh umq vitest.tar
  5. [root@dev workspace]# /usr/bin/time -o timeoutput.txt ls
  6. archive.tar.gz golang output.txt sample1.txt temp.txt umq vitest.tar
  7. echo if.sh out.txt sample2.txt timeoutput.txt variables.sh welcome.txt
  8. else input.txt printf.sh showArgs.sh tools vitest
  9. [root@dev workspace]# cat timeoutput.txt
  10. 0.00user 0.00system 0:00.00elapsed 100%CPU (0avgtext+0avgdata 3184maxresident)k
  11. 0inputs+0outputs (0major+163minor)pagefaults 0swaps
  12. [root@dev workspace]#

文件名应该出现在选项-o之后。

选项-a可以配合-o使用,将命令执行时间追加到原文件的末尾:

  1. $ /usr/bin/time -a -o output.txt COMMAND

(3) 选项-f可以指定输出哪些统计信息及其格式。格式字符串包括一个或多个以%为前缀的参数。格式参数包括以下几种。

  • real 时间: %e
  • user 时间: %U
  • sys 时间: %S
  • 系统分页大小:%Z

通过结合格式参数以及其他文本,我们就可以创建格式化输出:

  1. $ /usr/bin/time -f "FORMAT STRING" COMMAND

例如:

  1. $ /usr/bin/time -f "Time: %U" -a -o timing.log uname
  2. Linux

其中,%U指定了user时间。

time命令将被计时的应用程序的输出发送到stdout,将自身的输出发送到stderr。我们可以用重定向操作符(>)重定向应用程序输出,用错误重定向操作符(2>)重定向time命令的输出。

例如:

  1. $ /usr/bin/time -f "Time: %U" uname> command_output.txt
  2. 2>time.log
  3. $ cat time.log
  4. Time: 0.00
  5. $ cat command_output.txt
  6. Linux

(4) 格式参数也可以报告内存使用情况。参数%M会显示所使用的最大内存(以KB为单位),参数%Z会显示系统页面大小:

  1. $ /usr/bin/time -f "Max: %M K\nPage size: %Z bytes" \
  2. ls>
  3. /dev/null
  4. Max: 996 K
  5. Page size: 4096 bytes

这里并不需要被计时的命令(ls)的输出,因此将标准输出重定向到了/dev/null

9.3.2 工作原理

time命令默认报告3类时间。

  • Real:指的是壁钟时间(wall clock time),也就是命令从开始执行到结束的时间。这段时2间包括其他进程所占用的时间片(time slice)以及进程被阻塞时所消耗的时间(例如,为等待I/O操作完成所用的时间)。
  • User:是指进程花费在用户模式(内核模式之外)中的 CPU 时间。这是执行进程所花费的时间。执行其他进程以及花费在阻塞状态中的时间并没有计算在内。
  • Sys:是指进程花费在内核中的CPU时间。它代表在内核中执行系统调用所使用的时间,这和库代码(library code)不同,后者仍旧运行在用户空间。与“user时间”类似,这也是真正由进程使用的CPU 时间。参考表 9-1,其中简要描述了内核模式(也称为监督模式)和系统调用机制。

time 命令给出了进程的很多细节信息。其中包括退出状态、接收到的信号数量以及进程上下文的切换次数等。这些信息都可以通过给选项-f提供相应的格式化字符串来显示。

9-1 展示了一些值得注意的参数。
9-1

参 数 描 述
%C 被计时的命令名称以及命令行参数
%D 进程非共享数据区的平均大小,以KB为单位
%E 进程使用的real时间(壁钟时间),显示格式为[小时:]分钟:秒
%x 命令的退出状态
%k 进程接收到的信号数量
%W 进程被交换出主存的次数
%Z 以字节为单位系统的页面大小。这是一个系统常量,但在不同的系统中,这个常量值也不同
%P 进程所获得的CPU时间百分比。这个值等于user + system时间除以总运行时间。结果以百分比形式显示
%K 进程的平均总内存使用量(data+stack+text),以KB为单位
%w 进程主动进行上下文切换的次数,例如等待I/O操作完成
%c 进程被迫进行上下文切换的次数(由于时间片到期)