BufferedOutputStream
ラッピングの使用をお勧めしFileOutputStream
ます。andをいじってもパフォーマンスが向上するとは思えません。また、その方法を使用すると、保守が困難なコードが多数残ることになります。ByteBuffer
FileChannel
理由は非常に単純です。どのアプローチを採用しても、必要な手順は同じです。
- バイトを生成します。これをどのように行う予定なのかは述べていません。これにより、追加レベルの一時的なバッファリングが方程式に導入される可能性があります。ただし、Java データはバイトに変換する必要があります。
- バイトをバッファに蓄積します。データを書き込む前にバッファリングして、大量の小さな書き込みを行わないようにする必要があります。それは当然です。しかし、そのバッファーが存在する場所は重要ではありません。
- JNI バリアを越えて、バイトを Java ヒープから C ヒープに移動します。ファイルの書き込みはネイティブ操作であり、Java ヒープから直接読み取ることはありません。したがって、Java ヒープにバッファリングしてから、バッファリングされたバイトを移動するか、ダイレクトにバッファリングするかに関係
ByteBuffer
なく (そうです、ダイレクトバッファが必要です)、依然としてバイトを移動しています。を使用してより多くの JNI 呼び出しを行うことになりますが、それByteBuffer
は限界費用です。
- Invoke
fwrite
は、C ヒープからカーネルが保持するディスク バッファーにバイトをコピーするカーネル呼び出しです。
- カーネル バッファをディスクに書き込みます。ディスクは低速であるため、これは他のすべての手順を組み合わせたものよりも重要です。
これらの手順をどのように実装するかによって、数マイクロ秒の増減が生じる場合がありますが、基本的な手順を変更することはできません。
は、ステップ #5 が実際に行われるようにするために、FileChannel
を呼び出すオプションを提供します。基になる呼び出しはバイトが書き込まれるまで返されないため、force()
これは実際には全体的なパフォーマンスを低下させる可能性があります。fsync
本当にやりたい場合は、基になるストリームからいつでもチャネルを取得できます。
結論: あなたが実際に IO バウンドであることに賭けても構わないと思っています。より良いハードウェアを保存するための治療法はありません。