ファイルを繰り返すには2つの方法があります。
-ループの使用
for
:for f in *; do echo "$f" done
使用
find
:find * -prune | while read f; do echo "$f" done
2つのループが同じファイルのリストを見つけると仮定すると、2つのオプションの違いは何ですかパフォーマンスそして処理?
ベストアンサー1
私は2259個のエントリがあるディレクトリでこれを試み、time
コマンドを使用しました。
出力time for f in *; do echo "$f"; done
(ファイルを除く!)は次のとおりです。
real 0m0.062s
user 0m0.036s
sys 0m0.012s
出力time find * -prune | while read f; do echo "$f"; done
(ファイルを除く!)は次のとおりです。
real 0m0.131s
user 0m0.056s
sys 0m0.060s
キャッシュミスを排除するために、各コマンドを複数回実行します。これは、出力を使用してパイピングする(について)を維持することbash
(for i in ...)がより速いことを示しています。find
bash
完璧にするために、find
あなたの例ではパイプが完全に重複しているので、パイプを削除しました。ただ出力は次find * -prune
のとおりです
real 0m0.053s
user 0m0.016s
sys 0m0.024s
またtime echo *
(出力は改行で区切られません。)
real 0m0.009s
user 0m0.008s
sys 0m0.000s
echo *
この時点でより速い理由は、改行をあまり出力しないため、出力があまりスクロールしないためだと思います。テストしてみましょう...
time find * -prune | while read f; do echo "$f"; done > /dev/null
生産する:
real 0m0.109s
user 0m0.076s
sys 0m0.032s
そしてtime find * -prune > /dev/null
出力は次のようになります。
real 0m0.027s
user 0m0.008s
sys 0m0.012s
そしてtime for f in *; do echo "$f"; done > /dev/null
以下を作ります:
real 0m0.040s
user 0m0.036s
sys 0m0.004s
最後に:time echo * > /dev/null
収率:
real 0m0.011s
user 0m0.012s
sys 0m0.000s
いくつかの変動はランダムな要因として説明されるかもしれませんが、これは明らかです。
- 出力速度が遅い
- パイプラインのコストが少し
for f in *; do ...
find * -prune
それ自体より遅いですが、パイプに関連する胃構造の場合は高速です。
また、どちらの方法も空白のある名前をうまく処理するようです。
編集する:
find . -maxdepth 1 > /dev/null
時間が経つにつれてfind * -prune > /dev/null
:
time find . -maxdepth 1 > /dev/null
:
real 0m0.018s
user 0m0.008s
sys 0m0.008s
find * -prune > /dev/null
:
real 0m0.031s
user 0m0.020s
sys 0m0.008s
したがって、追加の結論は次のとおりです。
find * -prune
以前よりも遅い場合は、シェルがfind . -maxdepth 1
globを処理してからfind
。find . -prune
.
その他のテスト time find . -maxdepth 1 -exec echo {} \; >/dev/null
::
real 0m3.389s
user 0m0.040s
sys 0m0.412s
結論として:
- これまでに最も遅い方法です。このアプローチを提案する回答の説明で指摘したように、各引数に対してシェルが生成されます。