web-dev-qa-db-ja.com

ストリームを使用したファイルI / O-最適なメモリバッファーサイズ

大規模な(趣味の)プロジェクトを支援する小さなI/Oライブラリを作成しています。このライブラリの一部は、FileStreamオブジェクトを介して読み書きされるファイルに対してさまざまな機能を実行します。 StreamReader.Read(...)パスごとに、

メインアプリで進行情報を表示するために使用されるイベントを起動します。ループ内で行われる処理はさまざまですが、時間がかかりすぎません(たとえば、単純なファイルコピーであるか、暗号化を伴う場合があります)。

私の主な質問は次のとおりです。使用するのに最適なメモリバッファサイズはどれくらいですか。物理ディスクレイアウトについて考えると、2kを選択できます。これはCDセクターサイズをカバーし、512バイトのハードディスクセクターのニース倍数です。抽象ツリーの上位では、一度にFATクラスター全体を読み取ることができる、より大きなバッファーを使用できます。今日のPCでは、より多くのメモリを必要とするオプション(たとえば、数MiB)を使用できますが、UIの更新とユーザーの応答が遅いアプリケーションを認識するまでの時間が長くなります。

余談ですが、最終的には、FTP/HTTPサーバー(ローカルネットワーク/高速DSL経由)でホストされるファイルに同様のインターフェイスを提供したいと考えています。それらに最適なメモリバッファーサイズは何ですか(これも、応答性とパフォーマンスのバランスをとる "ベストケース"トレードオフ)。

50
AJ.

ファイルは既にファイルシステムキャッシュによってバッファリングされています。 FileStreamがネイティブのWindows ReadFile()API呼び出しを強制してバッファーをいっぱいにしすぎることのないバッファーサイズを選択する必要があります。キロバイトを下回らないでください。16KBを超えると、メモリが無駄になり、CPUの処理に不向きになります L1キャッシュ (通常16または32 KBのデータ)。

4 KBは、偶然に仮想メモリページに正確に及ぶ場合でも、従来の選択肢です。プロファイルを作成することは困難です。キャッシュファイルの読み取りにかかる時間を測定することになります。キャッシュでデータが使用可能な場合、RAM速度、5ギガバイト/秒以上で実行されます。テストを2回実行するとキャッシュに格納され、それは起こりません。ファイルI/Oは、ディスクドライブまたは [〜#〜] nic [〜#〜] によって完全に支配されており、非常に遅いため、データのコピーはピーナッツです4 KBは正常に機能します。

71
Hans Passant

ストリームオブジェクトを介して直接ファイルを処理する場合、通常は4096バイトを使用します。複数のI/Oエリア(ローカルファイルシステム、LAN/ [〜#〜] smb [〜#〜] 、ネットワークストリームなど)で合理的に効果があるようですが、私はしていませんそれか何かをプロファイルしました。昔、私はいくつかの例がそのサイズを使用しているのを見ましたが、それは私の記憶に残っています。だからといって、それが最高だというわけではありません。

4
Nate

"場合によります"。

最適なサイズを判断するには、さまざまなバッファーサイズでアプリケーションをテストする必要があります。事前に推測することはできません。

3
John Saunders