原文地址:http://m.biancheng.net/linux/time.htmlphp
這裏咱們要學習的 time 命令是用來測量 Linux 程序執行時間的命令,而不是用來顯示系統時間的命令。不是吧,這也太分裂了吧,那顯示系統時間的命令是什麼呢?是 date,立刻百度一下,你就清楚了。
Linux 手冊中是這樣介紹 time 命令的:「time a simple command or give resource usage」,即測量命令的執行時間,或者給出系統資源的使用狀況。html
若是你想查看一條命令(好比 ls)到底執行了多長時間,咱們能夠這樣作:mysql
[roc@roclinux ~]$ time ls program public_html repo rocscm real 0m0.002s user 0m0.002s sys 0m0.000s
看到沒有,執行時間一會兒就統計出來了。但輸出內容中有三個統計時間,real、user 和 sys,它們都表明什麼含義呢?哪一個纔是 ls 命令的執行時間呢?下面咱們就一塊兒來看看這三個統計時間。
(1) real:從進程 ls 開始執行到完成所耗費的 CPU 總時間。該時間包括 ls 進程執行時實際使用的 CPU 時間,ls 進程耗費在阻塞上的時間(如等待完成 I/O 操做)和其餘進程所耗費的時間(Linux 是多進程系統,ls 在執行過程當中,可能會有別的進程搶佔 CPU)。
(2) user:進程 ls 執行用戶態代碼所耗費的 CPU 時間。該時間僅指 ls 進程執行時實際使用的 CPU 時間,而不包括其餘進程所使用的時間和本進程阻塞的時間。
(3) sys:進程 ls 在內核態運行所耗費的 CPU 時間,即執行內核系統調用所耗費的 CPU 時間。
如今,咱們應該對這三個時間很是清楚了吧。ls 命令的真正執行時間是多少?答案就是 user+sys 的時間,但通常狀況下,real=user+sys,於是咱們就使用 real 的時間做爲 ls 的執行時間了(注意,這裏會有幾個坑,咱們將在後面進行介紹)。
好了,time 的最基本用法介紹完畢,就這麼簡單。linux
上面說 real 時間中會有幾個坑,下面咱們就來詳細地看一看。
情景一:sql
[roc@roclinux ~]$ time sudo find / -name php.ini real 0m0.193s user 0m0.076s sys 0m0.115s
咦,是我數學很差,仍是命令執行出錯了呢?爲何 0.193s(real)>0.076s(user)+0.115s(sys),而不是相等呢?哈哈,同窗,你挺細心的嘛。這既不是你的數學很差,也不是命令執行出錯,而是咱們對命令執行時間的理解有幾個誤區。緩存
誤區一:服務器
real_time=user_time+sys_time
若是你認爲上面的等式必定成立的話,那麼請你再理解一下前面關於 real、user 和 sys 的介紹。在前面的表述中,real time 是包含了其餘進程的執行時間和進程阻塞時間的,而 usr time+sys time 顯然是不包括其餘進程的執行時間和進程阻塞時間的。所以,real_time>user_time+sys_time 是很是有可能的。ide
誤區二:工具
real_time>user_time+sys_time
根據上面的分析,這個關係式應該是成立的吧?嘿嘿,不必定喲。通常來講,在單核 CPU 系統中,這個關係式是成立的,但若是咱們的系統是多核 CPU 的話,而有些程序是可以同時利用到多核 CPU 的計算能力的,在這種狀況下這個關係式就不成立了。
程序利用多核 CPU 的計算能力,能夠並行地處理多項事務。就像一件工做,原來是一個 CPU 核去作,如今是兩個 CPU 核並行作,那麼完成一樣工做所花費的總時間是 user_time+sys_time,而兩我的並行作卻可以在更短的時間內完成,耗時爲 real_time。所以,這種狀況下,便出現了 real_time<user_time+sys_time 的狀況。學習
誤區三:
real_time<user_time+sys_time
多核狀況下,real_time<user_time+sys_time 是成立的,那單核呢?顯然是 real_time>user_time+sys_time。
上面的三個誤區有點繞,但結論很重要,就是 real_time 和 user_time+sys_time 的大小關係不是恆久不變的,你須要瞭解你的 Linux 服務器,是單核,仍是多核,這樣才能正確地肯定它們的關係。
情景二:
[roc@roclinux ~]$ time sudo find / -name mysql.sh /etc/profile.d/mysql.sh real 0m6.776s user 0m1.101s sys 0m1.363s
咱們執行 find/-name mysql.sh 搜索文件的命令,顯示的命令耗時是 6.776 秒。
若是咱們再執行一次徹底相同的命令:
[roc@roclinux ~]$ time sudo find / -name mysql.sh /etc/profile.d/mysql.sh real 0m3.059s user 0m1.189s sys 0m1.435s
咦,怎麼 real 的時間縮減到了 3.059 秒了,生生少了 3 秒多鍾,這又是怎麼回事呢?爲何一樣的命令在第二次執行時快這麼多呢?
這個現象跟 Linux 操做系統的運行原理有關,find 命令在第一次執行後,系統會對一些文件作緩存,在第二次執行時,就正好使用到了這些緩存中的數據,所以執行速度就變快了不少。
看過這個示例後,若是仍有同窗不問青紅皁白地抱怨 time 命令的計時偏差大,那可真是冤枉 time 啦。
time 的 man 手冊中說,它不只能夠測量運行時間,還能夠測量內存、I/O 等的使用狀況,但爲何上面示例中的 time 命令的結果中卻沒有顯示出這些信息呢?難道是 man 手冊出現了錯誤?
NO,NO,NO(重要的事情要說三遍),其實上面使用的 time 真的是「巧婦難爲無米之炊」,咱們以前所用的 time 命令是 Bash 的內置命令,功能比較弱;而更強大的 time 命令隱藏在 /usr/bin/ 目錄下,這個命令纔是世外高人。
若是咱們在 /user/bin/ 中並無找到傳說中那個強大的 time 命令,那麼應該是沒有安裝 time 這個工具,安裝方法也很簡單:
[root@roclinux ~]# yum install time
安裝完成後,咱們就一塊兒來見識 time 命令的廬山真面目吧!咱們特地在 time 命令前加了一個斜線(\),就是爲了調用那個強大的 time 命令,而非 Bash 內置的 time 命令。
[root@roclinux ~]# \time ls bin dev lib media proc seLinux tmp boot etc lib64 mnt root srv usr cgroup home lost+found opt sbin sys var 0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 956maxresident)k 0inputs+0outputs (0major+289minor)pagefaults 0swaps
請注意輸出內容中的最後兩行,打印了不少指標數據,但彷佛有點晦澀難懂。這時咱們可使用一個 -v 選項,這樣能夠打印出更詳細的信息。
[root@roclinux /]# \time -v ls bin dev lib media proc seLinux tmp boot etc lib64 mnt root srv usr cgroup home lost+found opt sbin sys var Command being timed: "ls" User time (seconds): 0.00 System time (seconds): 0.00 Percent of CPU this job got: 0% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00 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): 956 Average resident set size (kbytes): 0 Major (requiring I/O) page faults: 0 Minor (reclaiming a frame) page faults: 292 Voluntary context switches: 1 Involuntary context switches: 1 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
注意,上面的 Elapsed(wall clock)time(h:mm:ss or m:ss):0:00.00,值是 0,難道執行 ls 命令沒有消耗時間?
非也,事情的真相是這樣的:在 time 命令的輸出中,Elapsed time 是經過系統調用 gettimeofday 獲取到的結束時間和起始時間相減獲得的。所以,time 對於運行時間較短的任務計時時,會產生必定偏差。time 命令輸出的時間統計精度基本在 10 毫秒級。
原來是精度的問題啊,少於 10 毫秒的程序,真的是連 time 也沒法精確計時。
time 命令能夠顯示的資源共有三大項,分別是:時間、內存和 I/O。下面來具體看看 time 命令都顯示了哪些指標數據。