回答編集履歴
2
補足説明
test
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
Unix/Linux系の全てのファイルシステムを知っているわけではないですが、一般にディレクトリーの構造は、可変長のディレクトリーエントリー(可変長のファイル名と管理情報)が並んだ形式になっていて、データベースのような索引は無いので、ファイルを探すには先頭から見つかるまでディレクトリーファイルを読む必要があります。例えば、手元の`/usr/bin`は36KBなので、`/usr/bin/ls`の管理情報を知るために、平均すると18KBのファイルを読むことになります。
|
7
7
|
|
8
8
|
質問の例だと、ファイル名が40バイトくらい(ちゃんと数えてませんが)のようなので、管理情報込みで1つのディレクトリーエントリーが60バイトだと仮定します。で、ファイルが1万6000個あったとすると、1つのディレクトリーに入れた場合、ディレクトリーサイズは、960,000 で、ファイルオープンや削除などをするために1ファイルの管理情報を得るために、平均480,000バイト読むことになります。
|
9
|
-
これを1000個ずつ16分割すると、親ディレクトリーサイズは960で平均480バイト読む。子ディレクトリーサイズは60,000で平均30,000バイト読むので、親子合計で30,480バイトと、1ディレクトリーの場合の1/10以下です(16分割なのでおおよそ16分の1)。つまりメモリーのキャッシュやバッファの効果を無視すると十倍以上速い。
|
9
|
+
これを1000個ずつ16分割すると、親ディレクトリーサイズは960で平均480バイト読む。子ディレクトリーサイズは60,000で平均30,000バイト読むので、親子合計で30,480バイトと、1ディレクトリーの場合の1/10以下です(16分割なのでおおよそ16分の1)。つまりメモリーのキャッシュやバッファの効果を無視すると十倍以上速い。(実際にはストレージの読み書きはバイト単位じゃなくてセクター単位なので、バイト数をセクターサイズで割って切り上げた回数の読み書きが発生します)
|
10
10
|
|
11
11
|
あと、ディレクトリーエントリーは可変長なので、ファイル名の長さが異なるファイルを追加・削除を繰り返すと、空き領域の断片化が発生して、ディレクトリーサイズが肥大します。手元の`/tmp`はファイル数18個なのにサイズが112KBとかなり肥大化してます。作り直せば4KBで収まるはず。
|
12
12
|
なので、キャッシュファイルの格納など、大量のファイルの追加削除が発生する場合は、ファイル名の長さを一定にすることが多いようです。ファイル名の長さが一定なら、全てのディレクトリーエントリーのサイズが同一で、削除したファイルの場所をそのまま再利用できるので、肥大化しません。肥大化すると読む量が増えるので、これも高速化のコツですね。
|
1
補足
test
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
Unix/Linux系の全てのファイルシステムを知っているわけではないですが、一般にディレクトリーの構造は、可変長のディレクトリーエントリー(可変長のファイル名と管理情報)が並んだ形式になっていて、データベースのような索引は無いので、ファイルを探すには先頭から見つかるまでディレクトリーファイルを読む必要があります。例えば、手元の`/usr/bin`は36KBなので、`/usr/bin/ls`の管理情報を知るために、平均すると18KBのファイルを読むことになります。
|
7
7
|
|
8
8
|
質問の例だと、ファイル名が40バイトくらい(ちゃんと数えてませんが)のようなので、管理情報込みで1つのディレクトリーエントリーが60バイトだと仮定します。で、ファイルが1万6000個あったとすると、1つのディレクトリーに入れた場合、ディレクトリーサイズは、960,000 で、ファイルオープンや削除などをするために1ファイルの管理情報を得るために、平均480,000バイト読むことになります。
|
9
|
-
これを1000個ずつ16分割すると、親ディレクトリーサイズは960で平均480バイト読む。子ディレクトリーサイズは60,000で平均30,000バイト読むので、親子合計で30,480バイトと、1ディレクトリーの場合の1/10以下です。つまりメモリーのキャッシュやバッファの効果を無視すると十倍以上速い。
|
9
|
+
これを1000個ずつ16分割すると、親ディレクトリーサイズは960で平均480バイト読む。子ディレクトリーサイズは60,000で平均30,000バイト読むので、親子合計で30,480バイトと、1ディレクトリーの場合の1/10以下です(16分割なのでおおよそ16分の1)。つまりメモリーのキャッシュやバッファの効果を無視すると十倍以上速い。
|
10
10
|
|
11
11
|
あと、ディレクトリーエントリーは可変長なので、ファイル名の長さが異なるファイルを追加・削除を繰り返すと、空き領域の断片化が発生して、ディレクトリーサイズが肥大します。手元の`/tmp`はファイル数18個なのにサイズが112KBとかなり肥大化してます。作り直せば4KBで収まるはず。
|
12
12
|
なので、キャッシュファイルの格納など、大量のファイルの追加削除が発生する場合は、ファイル名の長さを一定にすることが多いようです。ファイル名の長さが一定なら、全てのディレクトリーエントリーのサイズが同一で、削除したファイルの場所をそのまま再利用できるので、肥大化しません。肥大化すると読む量が増えるので、これも高速化のコツですね。
|