Text-Processing
為什麼是尾文件 |tr (管道)比 sed 或 perl 快嗎?
我有一個包含大約一百萬行的文件,如下所示:
"ID" "1" "2" "00000687" 0 1 "00000421" 1 0 "00000421" 1 0 "00000421" 1 0
最後一行重複了超過一百萬次。從這個問題中獲得靈感,我嘗試了一些建議的解決方案,看看哪個更快。我原以為只有一個程序的解決方案會比使用管道的解決方案更快,因為它們只使用一個程序。但這些是我的測試結果:
tail -n +2 file.txt | tr -d \"
$ time tail -n +2 file.txt | tr -d \" 1> /dev/null real 0m0,032s user 0m0,020s sys 0m0,028s
sed '1d;s/"//g' file.txt
$ time sed '1d;s/"//g' file.txt 1> /dev/null real 0m0,410s user 0m0,399s sys 0m0,011s
perl -ne ' { s/"//g; print if $. > 1 }' file.txt
$ time perl -ne ' { s/"//g; print if $. > 1 }' file.txt 1> /dev/null real 0m0,379s user 0m0,367s sys 0m0,013s
我多次重複測試,我總是得到相似的數字。如您所見,
tail -n +2 file.txt | tr -d \"
比其他人快得多。為什麼?
它歸結為正在完成的工作量。
您的
tail | tr
命令最終執行以下操作:
- 讀到換行符;
- 輸出剩餘的所有內容,而不關心換行符;
in
tr
,閱讀,而不關心換行符,並輸出除 ‘"’ (固定字元)之外的所有內容。在解釋給定腳本後,您的
sed
命令最終會執行以下操作:
- 讀取直到換行,累積輸入;
- 如果這是第一行,請將其刪除;
- 解釋正則表達式後,用空替換所有雙引號;
- 輸出處理後的行;
- 循環直到文件結束。
在解釋給定腳本後,您的 Perl 命令最終會執行以下操作:
- 讀取直到換行,累積輸入;
- 解釋正則表達式後,用空替換所有雙引號;
- 如果這不是第一行,則輸出處理後的行;
- 循環直到文件結束。
尋找換行符最終會因大量輸入而變得昂貴。