「エコ」が「タッチ」よりはるかに速いのはなぜですか?

「エコ」が「タッチ」よりはるかに速いのはなぜですか?

ディレクトリ内のすべてのxmlファイルのタイムスタンプを現在の時刻に(再帰的に)更新しようとしています。私はMac OSX 10.8.5を使用しています。

約300,000個のファイルに対して、次のechoコマンドには次のものが必要です。10秒:

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

ただし、次のtouchコマンドには次のものが必要です。10分! :

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

エコーがタッチよりもはるかに速いのはなぜですか?

ベストアンサー1

Bashではtouch外部バイナリechoですが、内蔵ケース:

$ type echo
echo is a shell builtin
$ type touch
touch is /usr/bin/touch

touch外部バイナリであり、ファイルごとに一度呼び出されるので、シェルからtouch300,000のインスタンスを作成する必要があります。touchこれは長い時間がかかります。

echoしかし、これはシェル組み込み関数なので、シェル組み込み関数の実行にはまったくフォークは必要ありません。代わりに、現在のシェルはすべての操作を実行し、外部プロセスを作成しないため、非常に高速です。

以下は、シェル操作の2つの概要です。を使用すると、新しいプロセスをcloneするのに時間がかかることがわかりますtouch/bin/echo組み込みの代わりにシェルを使用すると、同様の結果が表示されます。


タッチを使う

$ strace -c -- bash -c 'for file in a{1..10000}; do touch "$file"; done'
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 56.20    0.030925           2     20000     10000 wait4
 38.12    0.020972           2     10000           clone
  4.67    0.002569           0     80006           rt_sigprocmask
  0.71    0.000388           0     20008           rt_sigaction
  0.27    0.000150           0     10000           rt_sigreturn
[...]

エコを使う

$ strace -c -- bash -c 'for file in b{1..10000}; do echo >> "$file"; done'
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 34.32    0.000685           0     50000           fcntl
 22.14    0.000442           0     10000           write
 19.59    0.000391           0     10011           open
 14.58    0.000291           0     20000           dup2
  8.37    0.000167           0     20013           close
[...]

おすすめ記事