我落后了幾年,但是:
在原始文章的“編輯4/5/6”中,您使用的是結構:
$ /usr/bin/time cat big_file | program_to_benchmark
這在幾個不同的方面是錯誤的:
你實際上是在計時“貓”的執行,而不是你的基準。“time”顯示的‘user’和‘sys’CPU使用率是‘cat’,而不是您的基準程序。更糟糕的是,“真實”時間也不一定準確。根據‘cat’和本地操作系統中管道的實現,‘cat’可能會寫入最后一個巨大緩沖區,并在讀者進程完成工作之前就退出。
使用‘cat’是不必要的,實際上適得其反;你在添加移動部件。如果您使用的是一個足夠老的系統(即使用單個CPU,并且-在某些代計算機中-I/O比CPU快)-僅僅是`cat‘正在運行這一事實就會嚴重影響結果。您還受輸入和輸出緩沖以及其他“cat”處理可能做的任何操作的限制。(這可能會給你帶來一個“貓的無用途”如果我是蘭德爾·施瓦茨。
一個更好的結構是:
$ /usr/bin/time program_to_benchmark < big_file
在這個聲明中,它是殼它打開bigfile,將其作為已經打開的文件描述符傳遞給您的程序(實際上是“time”,然后作為子進程執行您的程序)。100%的文件讀取嚴格來說是你想要測試的程序的責任。這可以讓您真正地閱讀它的性能,而不會出現虛假的復雜情況。
我將提到兩個可能但實際上是錯誤的,也可以考慮的“修正”(但我對它們的“編號”不同,因為在最初的文章中,這些都不是錯誤的):
答:你只需計時你的程序就可以“修復”這個問題:
$ cat big_file | /usr/bin/time program_to_benchmark
B.或根據整個管道的時間安排:
$ /usr/bin/time sh -c 'cat big_file | program_to_benchmark'
這些錯誤的原因與#2相同:它們仍然不必要地使用“cat”。我提到它們有幾個原因:
對于那些對POSIX外殼的I/O重定向設施不太滿意的人來說,它們更“自然”。
在某些情況下,“貓”是需要(例如:要讀取的文件需要某種訪問權限,并且您不希望將該權限授予要對其進行基準測試的程序:‘sudo cat/dev/sda區/usr/bin/time my_press_test-no-output’)
在實踐中,在現代機器上,在管道中添加的‘cat’可能沒有什么實際意義。
但我說的最后一件事有點猶豫。如果我們檢查“編輯5”的最后結果-
$ /usr/bin/time cat temp_big_file | wc -l0.01user 1.34system 0:01.83elapsed 74%CPU ...
-這聲稱“cat”在測試期間消耗了74%的CPU;實際上1.34/1.83約占74%。也許是一連串的:
$ /usr/bin/time wc -l < temp_big_file
剩下的0.49秒就好了!可能不會:這里的`cat‘必須支付從’disk‘(實際上是緩沖區緩存)傳輸文件的read()系統調用(或等效的),以及管道寫入以將它們傳遞給’wc‘。正確的測試仍然需要執行這些read()調用;只有寫到管道和從管道讀取的調用才會被保存,而且這些調用應該相當便宜。
不過,我預計您將能夠測量“Cat file x WC-l”和“wc-l<file”之間的差異,并發現明顯的(2位數的百分比)差異。每一次較慢的測試都將在絕對時間內支付類似的懲罰;然而,這將相當于其較長時間的一小部分。
實際上,我在Linux 3.13(Ubuntu14.04)系統上對1.5G垃圾文件做了一些快速測試,獲得了以下結果(這些結果實際上是“3中最好的”結果;當然,在啟動緩存之后):
$ time wc -l < /tmp/junk
real 0.280s user 0.156s sys 0.124s (total cpu 0.280s)$ time cat /tmp/junk | wc -l
real 0.407s user 0.157s sys 0.618s (total cpu 0.775s)$ time sh -c 'cat /tmp/junk | wc -l'real 0.411s user 0.118s sys 0.660s (total cpu 0.778s)
請注意,這兩個管道結果聲稱占用的CPU時間(用戶+sys)比實時時間要多。這是因為我使用的是shell(Bash)內置的‘time’命令,它知道管道;我在一臺多核機器上,管道中的單獨進程可以使用不同的內核,積累CPU時間比實時快。使用/usr/bin/time,我看到的CPU時間比實時的要小-表明它只能對命令行上傳遞給它的單個管道元素進行計時。另外,shell的輸出給出毫秒,而/usr/bin/time只給出百分之一秒。
因此,在“wc-l”的效率級別上,“cat”產生了巨大的差異:409/283=1.453或45.3%的實時,775/280=2.768,或高達177%的使用CPU!在我的隨機測試箱里。
我應該補充一點,在這些測試風格之間至少還有一個顯著的區別,我不能說它是有利的還是錯誤的;你必須自己決定:
當您運行`Cat bix_file\/usr/bin/time my_Programm‘時,您的程序正在接收來自管道的輸入,其速度與“cat”所發送的速度正好相同,并且以不大于“cat”編寫的塊的方式進行。
當您運行`/usr/bin/timemy_Program<Big_file‘時,您的程序將收到一個打開的文件描述符到實際文件。你的節目-或在許多情況下,編寫它的語言的I/O庫-當顯示引用常規文件的文件描述符時,可能會采取不同的操作。它可以使用mmap(2)將輸入文件映射到其地址空間,而不是使用顯式讀取(2)系統調用。這些差異對基準結果的影響可能比運行“cat”二進制文件的成本小得多。
當然,如果相同的程序在兩種情況下的執行情況明顯不同,這將是一個有趣的基準結果。它表明,實際上,程序或其I/O庫是做一些有趣的事情,比如使用mmap()。因此,在實踐中,最好是以兩種方式來運行基準;也許可以用一些小因素來“原諒”運行`cat‘本身的成本,從而將`cat’結果打折扣。