5000 個の小さなデータ ブロック (最小サイズ: 351 バイト、最大サイズ: 386 バイト、平均サイズ: 385 バイト) のリストを生成し、それらを個別のファイルとしてディレクトリに書き込むテスト コードがあります。平均書き込み時間はファイルあたり約 5 ミリ秒です。
まったく同じコードを使用しながら、5000 個の異なるブロックを書き込む代わりに、同じデータを何度も繰り返すと (たとえば、最初の 10 ブロックを 500 回書き込む)、平均書き込み時間はファイルあたり 2 ミリ秒未満になります。これは、データが同じであるため、ファイル システムが何らかの方法で書き込みを最適化できるかのようです。
この動作について説明できる人はいますか?
8 GB の RAM を搭載した Surface Pro 4 - i5 プロセッサでテストし、内蔵ソリッド ステート ドライブに書き込みます。オペレーティング システムは Windows 10 です。
テストコード:
const int count = 5_000;
// Generate a list of count small byte arrays: min. size: 351, max size: 386, average size: 385
var bytes = SerializeObjects( count );
// Write them all to disk as individual files
var watch = Stopwatch.StartNew();
for ( var i = 0; i < count; i++ )
{
File.WriteAllBytes(
Path.Combine( _directory, Guid.NewGuid() + ".xml" ),
bytes[ i ]
);
}
watch.Stop();
// Timed at: around 5ms per file
Console.WriteLine( "Wrote {0:n0} files in {1:n0} ms ({2:n3} ms per file)", count, watch.ElapsedMilliseconds, (double)watch.ElapsedMilliseconds / count );
WriteAllBytes()
書き込み呼び出しを変更するとbytes[ i % 10 ]
(最初の 10 個の値を何度も繰り返す)、ファイルあたりの時間は 2 ミリ秒未満に短縮されます。
アップデート
重複排除ではありません:
PS > Get-DedupProperties C
Get-DedupProperties : Deduplication feature is not available
答え1
Server 2012 以降の Windows バージョンでは、データの「重複排除」がサポートされています。システムでこれが有効になっている可能性があり、その場合、OS は重複書き込みを検出し、共通のファイル システム データに「ポインター」を割り当てます。これにより、NT はディレクトリ ブロックのみを更新し、重複ファイル用に新しいファイル システム ブロックを割り当てて書き込む必要がなくなるため、I/O が大幅に削減されます。