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