time命令_Linux time命令:測量命令的執行時間或者系統資源的使用情況(轉)


原文地址:http://m.biancheng.net/linux/time.html

這里我們要學習的 time 命令是用來測量 Linux 程序執行時間的命令,而不是用來顯示系統時間的命令。不是吧,這也太分裂了吧,那顯示系統時間的命令是什么呢?是 date,馬上百度一下,你就清楚了。

Linux 手冊中是這樣介紹 time 命令的:“time a simple command or give resource usage”,即測量命令的執行時間,或者給出系統資源的使用情況。

time 的簡單用法

如果你想查看一條命令(比如 ls)到底執行了多長時間,我們可以這樣做:

[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 的最基本用法介紹完畢,就這么簡單。

消失的時間

上面說 real 時間中會有幾個坑,下面我們就來詳細地看一看。

情景一:

[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 是非常有可能的。

誤區二:

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 命令輸出指標介紹

time 命令可以顯示的資源共有三大項,分別是:時間、內存和 I/O。下面來具體看看 time 命令都顯示了哪些指標數據。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM