失礼:以下の「高速」方法は、遅い方法よりも60倍速くはありません。 30倍速くなりました。私はこの間違いをその時に責める。 (午前3時は私が明確に考えるのに最適な時間ではありません:)..
更新:テスト時間の概要を追加しました(下)。
速度要素には2つの問題が関係しているようです。
- 使用されるコマンドの選択(下記のタイミング比較を参照)
- ディレクトリに多数のファイルがあるという特性は…「大きなものは悪いもの」のように見えます。数が増加すると、状況は不均衡に遅くなります。
すべてのテストは100万のファイルを使用して行われました。
(リアルタイム、ユーザー時間、システム時間はテストスクリプトにあります。)
テストスクリプトは以下にあります。Paste.ubuntu.com
#
# 1 million files
# ===============
#
# |time |new dir |Files added in ASCENDING order
# +---- +------- +-------------------------------------------------
# real 01m 33s Add files only (ASCENDING order) ...just for ref.
# real 02m 04s Add files, and make 'rm' source (ASCENDING order)
# Add files, and make 'rm' source (DESCENDING order)
# real 00m 01s Count of filenames
# real 00m 01s List of filenames, one per line
# ---- ------- ------
# real 01m 34s 'rm -rf dir'
# real 01m 33s 'rm filename' via rm1000filesPerCall (1000 files per 'rm' call)
# real 01m 40s 'rm filename' via ASCENDING algorithm (1000 files per 'rm' call)
# real 01m 46s 'rm filename' via DESCENDING algorithm (1000 files per 'rm' call)
# real 21m 14s 'rm -r dir'
# real 21m 27s 'find dir -name "hello*" -print0 | xargs -0 -n 1000 rm'
# real 21m 56s 'find dir -name "hello*" -delete'
# real 23m 09s 'find dir -name "hello*" -print0 | xargs -0 -P 0 rm'
# real 39m 44s 'rm filename' (one file per rm call) ASCENDING
# real 47m 26s 'rm filename' (one file per rm call) UNSORTED
#
最近作成して削除しました。1010,000個の空のテストファイル。名前(例rm filename
:)でファイルを削除するには巨大な2つの方法の時間差...
どちらの方法もまったく同じrm filename
コマンドを使用します。
更新:このコマンドはまったく同じではないことがわかりました...そのうちの1つは、「rm」として一度に1000個のファイル名を送信しています...シェル支柱拡張の問題です。各ファイル名がフィーダファイルに書き込まれるようです。 1行がありますが、実際には1行に1000本あります。
ファイル名はwhile read
「フィードファイル」を介してループに渡されます。
フィードファイルはこれらのメソッドの出力であり、次のいずれls -1 -f
かを除いてすべての点で同じです。
- これ遅いソートされていないフィーダーファイルを直接使用する方法
ls -1 -f
- これ早くメソッドは、ソートされていない同じファイルのソートされたバージョンを使用します。
ここでは、ソートが問題なのか、ソートされたフィードファイルがファイルが生成された順序と一致するのかわかりません(単純な昇順整数アルゴリズムを使用しました)。
100万個のファイルについて、早く rm filename
方法は60比較する遅い方法... 繰り返しますが、これが「ソート」の問題なのか、背後のハッシュテーブルの問題なのかはわかりません...単純なソートの問題ではないようです。なぜ意図的にls -1 -f
私にソート解除新しく追加された「ソートされた」ファイル名シーケンスのリスト...
次の1000万ファイルを削除するのに数日(例えば数日)がかかるのを防ぐために、ここで何が起こっているのかを知りたいです。 :) ....多くの選択肢を試したので、「仕事」と言います。関連ファイルの数に応じて、関連項目が不均衡に増加します。それでテストだけしました。1何千もの詳細
注:名前の「ソートされたリスト」でファイルを削除することは、実際にはrm -rf
「ソートされたリスト」方法よりも2倍高速です。
AND:rm -r
「ソートされたリスト」アプローチより30倍遅い
…しかし、ここで質問は「ソート」されていますか?それとも、ext4で使用されるハッシュ(または他の)保存方法ともっと関連がありますか?
私を混乱させることは、各呼び出しが以前の呼び出しrm filename
とは何の関係もないということです。 (少なくとも「bash」の観点から)
私はUbuntu/bash/'ext4'/SATA IIドライブを使用しています。
答え1
rm -r は再帰のために遅くなると予想されます。ディレクトリ構造の深さ優先探索を実行する必要があります。
それでは、1000万個のファイルをどのように生成しますか?どのような順序で繰り返されるスクリプトを使用していますか? 1.txt,2.txt,3.txt... もしそうなら、これらのファイルは同じ順序でHDDの連続したブロックに割り当てられます。したがって、同じ順序で削除する方が高速です。
"ls -f"は-aUを有効にします。これは再帰的なディレクトリの順序でリストされます。
答え2
ファイル構造を最適化する必要があります。だから代わりに
for i in $(seq 1 1000); do touch file.$i; done
次のように、よりスマートに実行します(bash仮定)。
function bucklocate()
{
hash=$(echo -n "$1"|md5sum|cut -f1);
echo -n "${hash:1:1}/${hash:7:1}/${hash:9:2}/$1";
}
hexdig="{0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f}"
eval mkdir -p $hexdig/$hexdig/$hexdig$hexdig
for i in $(seq 1 1000); do touch $(bucklocate file.$i); done
これで、この例ではmd5sum [1]を使用しているため、かなり遅くなります。次のようなものを使用すると、特定のファイル名を必要とせず、重複について心配する必要がない限り、応答性が向上します。反復可能には特定の名前が必要ですか?ハを願っています:)
mkdir -pv {0,1,2,3,4,5,6}/{0,1,2,3,4,5,6,7,8,9,10,12}
for a in $(seq 1 100); do i=$RANDOM; echo touch "$(($i%7))/$(($i%13))/file.$i"; done
もちろん、これはすべてハッシュテーブルの概念を急いで借りたものです。