Text-Processing

為什麼是尾文件 |tr (管道)比 sed 或 perl 快嗎?

  • May 22, 2020

我有一個包含大約一百萬行的文件,如下所示:

"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命令最終執行以下操作:

  • tail

    • 讀到換行符;
    • 輸出剩餘的所有內容,而不關心換行符;
  • in tr,閱讀,而不關心換行符,並輸出除 ‘"’ (固定字元)之外的所有內容。

在解釋給定腳本後,您的sed命令最終會執行以下操作:

  • 讀取直到換行,累積輸入;
  • 如果這是第一行,請將其刪除;
  • 解釋正則表達式後,用空替換所有雙引號;
  • 輸出處理後的行;
  • 循環直到文件結束。

在解釋給定腳本後,您的 Perl 命令最終會執行以下操作:

  • 讀取直到換行,累積輸入;
  • 解釋正則表達式後,用空替換所有雙引號;
  • 如果這不是第一行,則輸出處理後的行;
  • 循環直到文件結束。

尋找換行符最終會因大量輸入而變得昂貴。

引用自:https://unix.stackexchange.com/questions/588127