time的命令,用于测量命令的运行时间,还可以测量内存、I/O等的使用情况。
1 linux系统默认有两个time命令
1 一个是 bash 的内置命令,比较简单
2 一个是/usr/bin/time外部命令。
root@SD-20200928IIIF:~# type -a time
time is a shell keyword
time is /usr/bin/time
2 内置的time命令
查看脚本运行时间:
root@SD-20200928IIIF:~# time php demo.php
10000
real 0m0.122s
user 0m0.016s
sys 0m0.109s
查看shell运行时间:
root@SD-20200928IIIF:~# time find /etc/php/ -name "php.ini"
/etc/php/7.2/apache2/php.ini
/etc/php/7.2/cli/php.ini
real 0m0.016s
user 0m0.000s
sys 0m0.016s
输出结果统计了三个时间:
real:从进程开始执行到完成所耗费的 CPU 总时间。该时间包括进程执行时实际使用的 CPU 时间,进程耗费在阻塞上的时间(如等待完成 I/O 操作)和其他进程所耗费的时间(Linux 是多进程系统,ls 在执行过程中,可能会有别的进程抢占 CPU)。
user:进程 执行用户态代码所耗费的 CPU 时间。该时间仅指进程执行时实际使用的 CPU 时间,而不包括其他进程所使用的时间和本进程阻塞的时间。
sys:进程在内核态运行所耗费的 CPU 时间,即执行内核系统调用所耗费的 CPU 时间。
真正执行时间是多少?答案就是 user+sys 的时间,但一般情况下,real=user+sys,因而我们就使用 real 的时间作为程序的执行时间了。
2.1 real的几个坑
误区一:real_time=user_time+sys_time
real time 是包含了其他进程的执行时间和进程阻塞时间的,而 usr time+sys time 显然是不包括其他进程的执行时间和进程阻塞时间的。因此,real_time>user_time+sys_time 是非常有可能的。
误区二:real_time>user_time+sys_time
一般来说,在单核 CPU 系统中,这个关系式是成立的,但如果我们的系统是多核 CPU 的话,而有些程序是能够同时利用到多核 CPU 的计算能力的,在这种情况下这个关系式就不成立了。
程序利用多核 CPU 的计算能力,可以并行地处理多项事务。就像一件工作,原来是一个 CPU 核去做,现在是两个 CPU 核并行做,那么完成同样工作所花费的总时间是 user_time+sys_time,而两个人并行做却能够在更短的时间内完成,耗时为 real_time。因此,这种情况下,便出现了 real_time
误区三:real_time
多核情况下,real_timeuser_time+sys_time。
上面的三个误区有点绕,但结论很重要,就是 real_time 和 user_time+sys_time 的大小关系不是恒久不变的,你需要了解你的 Linux 服务器,是单核,还是多核,这样才能正确地确定它们的关系。
2.2 系统缓存
root@SD-20200928IIIF:~# time find /mnt/d/php_worker/php-command/ -name "*php" > /dev/null
real 0m0.025s
user 0m0.000s
sys 0m0.031s
root@SD-20200928IIIF:~# time find /mnt/d/php_worker/php-command/ -name "*php" > /dev/null
real 0m0.021s
user 0m0.016s
sys 0m0.000s
为什么同样的命令在第二次执行时快这么多呢?
这个现象跟 Linux 操作系统的运行原理有关,find 命令在第一次执行后,系统会对一些文件做缓存,在第二次执行时,就正好使用到了这些缓存中的数据,因此执行速度就变快了很多。
3 /usr/bin/time 命令
它不仅可以测量运行时间,还可以测量内存、I/O 等的使用情况
这里还用php这个脚本举例
# shell内置time命令
root@SD-20200928IIIF:~# time php demo.php
10000
real 0m0.095s
user 0m0.031s
sys 0m0.063s
# /usr/bin/time 命令
root@SD-20200928IIIF:~# /usr/bin/time php demo.php
10000
0.04user 0.07system 0:00.11elapsed 107%CPU (0avgtext+0avgdata 16476maxresident)k
0inputs+0outputs (0major+4801minor)pagefaults 0swaps
# /usr/bin/time 命令也可以使用 \time
root@SD-20200928IIIF:~# \time php demo.php
10000
0.03user 0.06system 0:00.09elapsed 96%CPU (0avgtext+0avgdata 16476maxresident)k
0inputs+0outputs (0major+4801minor)pagefaults 0swaps
/usr/bin/time 命令输出内容中的最后两行,打印了很多指标数据,但似乎有点晦涩难懂。这时我们可以使用一个 -v 选项,这样可以打印出更详细的格式化后的信息。
root@SD-20200928IIIF:~# \time -v php demo.php
10000
Command being timed: "php demo.php"
User time (seconds): 0.00
System time (seconds): 0.10
Percent of CPU this job got: 93%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.11
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 16476
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 4802
Voluntary context switches: 0
Involuntary context switches: 0
Swaps: 0
File system inputs: 0
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0
在 \time 命令的输出中,Elapsed time 是通过系统调用 gettimeofday 获取到的结束时间和起始时间相减得到的。因此,time 对于运行时间较短的任务计时时,会产生一定误差。time 命令输出的时间统计精度基本在 10 毫秒级。
3.1 time 命令输出指标介绍
time 命令可以显示的资源共有三大项,分别是:时间、内存和 I/O。下面来具体看看 time 命令都显示了哪些指标数据。
(1) 时间
指 标
含 义
Elapsed (wall clock) time
执行命令所花费的时间,格式是:[hour]:minute:second
System time
命令执行时在内核模式所花费的时间,单位是秒
User time
命令执行时在使用者模式所花费的时间,单位是秒
Percent of CPU this job got
命令执行时 CPU 的占用比例。 其实这个数字就是内核模式的 CPU 时间加上使用者模式的 CPU 时间除以总时间
(2) 内存
指 标
含 义
Maximum resident set size
执行程序所占用内存的最大值。单位是 KB
Average resident set size
执行程序所占用内存的平均值,单位是 KB
Average total size
执行程序所占用的内存总量(stack+data+text)的平均大小, 单位是 KB
Average unshared data size
执行程序所占用的私有数据区(unshared data area)的平均 大小,单位是 KB
Average stack size
执行程序所占用的私有堆栈(unshared stack)的平均大小, 单位是 KB
Average shared text size
执行程序间共享内容(shared text)的平均值,单位是 KB
Page size
系统内存页的大小,单位是 byte。对于同一个系统来说,这 是个常数
(3) I/O
指 标
含 义
Major (requiring I/O) page faults
此程序的主要内存页错误发生的次数。 所谓的主要内存页错误是指某一内存页己经詈换到 SWAP 分区中,又被其他程序使用过,该页的内容必须从 SWAP 分区里再读出来才能使用
Minor (reclaiming a frame) page faults
此程序的次要内存页错误发生的次数。 所谓的次要内存页错误是指某一内存页虽然己经詈换到 SWAP 中,但尚未被其他程序使用。此时该页的内容并未 被破坏,不必从 SWAP 分区里读出来即可直接使用
Swaps
此程序被交换到 SWAP 分区的次数
Involuntary context switches
此程序被强迫中断(如 CPU 时间耗尽)的次数
Voluntary context switches
此程序自愿中断(I/O 执行完毕,磁碟读取完成等)的次数
File system inputs
此程序所输入的文件数
File system outputs
此程序所输出的文件数
Socket messages received
此程序所收到的 Socket Message
Socket messages sent
此程序所送出的 Socket Message
Signals delivered
此程序所收到的信号数
Exit status
命令退出状态