ストリームをコピーしたりファイルを読み込んだりする必要があるときに、かなり長い間バッファを使用しています。
バッファサイズを2048または1024に設定するたびに、私の観点から見ると、バッファは「バケット」のようなものであり、私の「砂」(ストリーム)を私の土地(メモリ)のある部分から別の部分に運びます。
だから、私のバケット容量を増やすと、理論的にはより少ない移動が可能になりますか?これはプログラミングでやるべきことですか?
あるファイルから別のファイルにデータ構造をコピーしていて、バッファーを使用して、データを読み取ってから書き込むまでの間にデータを保存するとします。
データの読み取りと書き込みにはオーバーヘッドがあります。ディスクでは、ヘッドはセクターを見つけてトラックを読み書きする必要があります。メモリでは、メモリのチャンク(通常は一度に1〜8バイト)を移動するためのプロセッサ命令と、メモリの一部から別の部分へ、またはメモリとプロセッサまたはメモリとディスクの間でデータを移動するためのバス操作が必要です。読み取った各チャンクはループのどこかで処理され、チャンクが小さいほど、ループの実行回数が多くなります。
バッファが1バイトの場合、1バイトのデータを読み書きするたびにこのオーバーヘッドが発生します。この例では、ディスクは読み取りと書き込みを同時に行うことができないため、読み取りが完了するまで書き込みを待機する必要がある場合があります。 1バイトのファイルの場合、これが可能な最善の方法ですが、1 MBのファイルの場合は、非常に遅くなります。
10MBのバッファがあり、10MBのファイルをコピーしたい場合は、すべてをバッファに読み込んでから、1つのステップですべてを書き出すことができます。
さて、20GBのファイルをコピーしたい場合、おそらくそれほど多くのメモリがありません。そうしたとしても、すべてのプログラムがバッファに20GBのメモリを割り当てたとしても、何も残っていません。メモリを割り当てる場合、メモリを解放する必要があり、割り当てと解放の両方に時間がかかる場合があります。
ある種のクライアントがデータのチャンク全体を待っている場合は、小さいチャンクの方が良い場合があります。クライアントがいくつかのチャンクを取得し、残りが不要であることを知っている場合、クライアントは中止できます。または、ユーザーが何かが起こっていることを確認できるように、さらに待機している間、持っているものを表示できます。
バッファーを割り当てる前にコピーするデータの量がわかっている場合は、コピーするデータに最適なサイズのバッファーを作成できます。すべてのデータの正確なサイズ、またはデータが適切な数のチャンクでコピーされるのに十分な大きさ。推測する必要がある場合は、不明な目的のために1MB前後のサイズが妥当です。
最適なサイズのバッファを作成するには、それを使用するデータを調査する必要があります。ファイルをコピーする場合、コピーされるファイルの大部分はどれくらいの大きさですか?次に、適切なバッファーサイズを推測し、時間を計ります。サイズを調整して、もう一度時間を計ります。使用可能なメモリの合計により、最大サイズが制限される場合があります。最終的に、特定の目標に最適なバッファーサイズに到達します。
バッファには最適なサイズがあります。バッファーが小さすぎると、必要以上のシステムコールがトリガーされる可能性があります。一方、バッファーが大きすぎると、CPUキャッシュの不要なリロードがトリガーされる可能性があります。特定の状況でこの質問に答える最良の方法は、プロファイラーを使用することです。
答えは次のとおりです。残念ながら、あなたの質問に対する単一の答えはありません。変数の数(ハードウェアの速度、ストリームのソース、ファイルの読み取り元のディスクの種類、使用可能なメモリ、OSファイルキャッシュアルゴリズムなど)はすべて回答に影響します。
特定の状況では、パフォーマンス測定を行い、バッガーバッファーが役立つかどうかを確認することをお勧めします。
それはすべて、あなたが何をしていて、どのような機械を使っているかなどに依存します。別の数値を試して、何が起こるかを確認してください。
ただし、バッファが大きいほど、読み取りと書き込みが速くなることがわかりました。 1024と2048について話しているので、これについて言及します。実際に大きなバッファをいくつか試してください。あるケースでは、8Kbから100Kbに切り替えることで8倍の速度で読んでおり、1Mbまでの顕著な改善が見られました。
私はハードウェアの専門家ではありませんが、通常、コンピュータは個々のバイトコピーの速度の何倍もの速度で順次バイトコピーを実行します。多分それらは並行して物事をするかもしれません、多分それはキャッシュを通してデータをより速く移動します、多分それは魔法です。ただし、大きなバッファーと配列コピー(またはオプティマイザーが配列コピーに変換できるループ)を使用すると、lotの時間を節約できます。