一連のオブジェクト書き込み後にストリームをフラッシュするよりも、 ObjectOutputStream#writeObjectを個別に呼び出した後にOutputStreamをフラッシュする方が効率的ですか?(例:オブジェクトを書き込んで4回フラッシュするか、4回書き込んでから1回だけフラッシュするか?)
ObjectOutputStreamは内部でどのように機能しますか?
一連のオブジェクト書き込み後にストリームをフラッシュするよりも、 ObjectOutputStream#writeObjectを個別に呼び出した後にOutputStreamをフラッシュする方が効率的ですか?(例:オブジェクトを書き込んで4回フラッシュするか、4回書き込んでから1回だけフラッシュするか?)
ObjectOutputStreamは内部でどのように機能しますか?
Object[5]
たとえば、4つ(それぞれをフラッシュする)を送信する方がどういうわけか良いObject[20]
ですか?
それは良くありません。実際、パフォーマンスの観点からすると、おそらくもっと悪いでしょう。これらの各フラッシュは、OSレベルのTCP/IPスタックに「今すぐ」データを送信するように強制します。最後に1回だけフラッシュを実行する場合は、システムコールとネットワークトラフィックを節約する必要があります。
まだこれを行っていない場合は、とのBufferedOutputStream
間にを挿入すると、パフォーマンスに大きな違いが生じます。これにより、シリアル化されたデータがソケットストリームに書き込まれる前にメモリに蓄積されます。これにより、多くのシステムコールが節約される可能性があり、送信される実際のオブジェクトによっては、パフォーマンスが桁違いに向上する可能性があります。Socket
OutputStream
ObjectOutputStream
(4つのオブジェクトの表現はObject[5]
1つのオブジェクトよりも大きいためObject[20]
、最初のケースではパフォーマンスが低下します。ただし、これはせいぜいわずかであり、フラッシュやバッファリングの問題と比較するとごくわずかです。)
このストリームは内部でどのように機能しますか?
それはあまりにも一般的な質問であり、賢明に答えることはできません。このページのドキュメントからシリアル化について読んでおくことをお勧めします。
いいえ、ネットリンクがダウンする可能性が高く、部分的なデータが役立つと信じる理由がない限り、問題はありません。それ以外の場合は、理由もなくコードをより複雑にする方法のように聞こえます。
ObjectOutputStreamの唯一のパブリックコンストラクターを見るとOutputStream
、インスタンス化の基礎が必要であることがわかります。
ObjectStreamをいつどのようにフラッシュするかは、使用しているストリームのタイプに完全に依存します。(そして、これらすべてを考慮する際に、OutputStreamのすべての拡張機能がフラッシュの要求を尊重することが保証されているわけではないことに注意してください。javadocsの「コントラクト」で詳しく説明されているため、完全に実装に依存しません。)
しかし確かに、それについて推論し、コードをプルアップして実際に何が行われるかを確認することもできます。
基盤となるOutputStreamがデバイス(ソケットの場合はディスクやネットワークインターフェイスなど)のOSサービスを利用する必要がある場合、flush()の動作は完全にOSに依存します。たとえば、ソケットの出力ストリームを取得してから、ObjectOutputStreamをインスタンス化して、シリアル化されたオブジェクトをネットに書き込むことができます。ホストOSのTCP/IP実装を担当します。
より効率的なものは何ですか?
オブジェクトストリームがByteArrayOutputStreamをラップしている場合は、一連のreallocとSystem.arrayCopy()呼び出しを調べている可能性があります。バイト配列の実装により、各(内部)resize()操作のサイズが2倍になり、n個の(小さい)オブジェクトを書き込んで毎回フラッシュするとn個のreallocが発生する可能性はほとんどないためです。(ここで、nは適度に小さい数であると想定されます)。
ただし、ネットワークストリームをラップする場合は、ネットワーク書き込みに非常にコストがかかることに注意する必要があります。プロトコルで許可されている場合は、書き込みをチャンク化して(送信バッファーを埋めるために)、1回だけフラッシュする方がはるかに理にかなっています。