新建大量空檔案時,echo 比 touch 快上數十倍...嗎?



前言

  • 先前為了準備資料搬移腳本、準備 log 功能時,建立了不少空檔案。一般情況下,會用 touch 來建立空檔案,但是有時也會用 echo >> ${file} redirect file 來建立空檔案。
  • 好奇查了一下,紀錄兩者的差異



說明

基本的差別

在手動建立檔案時,速度幾乎沒有差別、小到人眼無法感知差異。

而兩者主要的差別在於,echo 是 built-in command,而 touch 是外部指令。

type 指令比較:

1
2
3
4
5
6
type echo
echo is a shell builtin


type touch
touch is /usr/bin/touch

大量檔案建立

如果是要一口氣建立幾十萬個檔案,這時速度就很明顯了。

根據 [1] 的測試的結果

echo,需要 10 秒:

1
2
3
for file in `find . -name "*.xml"`; do 
   echo >> $file
done

touch 則需要 10 分鐘、也就是 600 秒:

1
2
3
for file in `find . -name "*.xml"`; do
   touch $file
done

看起來似乎快上 60 倍!


我自己用 server 測試,創建 10000 個檔案,需要 33

1
2
3
4
5
time for i in {0..10000}; do touch ${i}.txt; done

real	0m33.610s
user	0m5.049s
sys	0m29.588s

而用 echo > redirect 的方式,只需要 0.9 秒:

1
2
3
4
5
time for i in {0..10000}; do echo > ${i}.txt; done

real	0m0.943s
user	0m0.200s
sys	0m0.674s

大概也快了 35 倍!


原因

因為 touch 是外部指令,每次執行都需要 fork 一個新的 process;

echo 是 built-in command,不需要 fork 新的 process,所以速度會快非常多。

等於前面提到的迴圈,每一次都會需要額外的時間來 call touch,當檔案數量多時,就會慢上不少。

如果單用 touch 的話

可是如果可以重複使用同一個 touch process,不用另外啟動,反而會更快:

1
2
3
4
5
time find ../ -name "*.txt" -printf '%P\n' | xargs touch

real	0m0.517s
user	0m0.028s
sys	0m0.425s

這樣只需要 0.5 秒,甚至比 for loop 裡面的 echo 快上一點點!

結論

  1. 如果只是建立少量檔案,兩者差異不大
  2. 如果是大量檔案、且使用 for loop,echo 的速度會快很多
  3. 如果是大量檔案、且使用 xargstouch 也可以快很多



REF

  1. https://unix.stackexchange.com/questions/123849/why-is-echo-so-much-faster-than-touch
Licensed under CC BY-NC-SA 4.0
最後更新 2024-05-08 10:47

主題 StackJimmy 設計