私はGzipOutputStreamとなBufferedOutputStreamを使用する必要がありますどのような順序
-
22-08-2019 - |
質問
誰もが私のような何かを行う必要があるかどうかをお勧めすることができます:
os = new GzipOutputStream(new BufferedOutputStream(...));
または
os = new BufferedOutputStream(new GzipOutputStream(...));
、より効率的であるどちら?私は全くなBufferedOutputStreamを使用する必要がありますか?
解決
私は
GzipOutputStream
とBufferedOutputStream
を使用する必要がありますどのような順序
オブジェクトストリームの場合、私は、入力と出力の両方のためにgzipストリームの周りにバッファされたストリームをラップすることはほとんど常にをしていることが分かっ大幅の速いです。オブジェクト小さく、より良いこれはやりました。良いか、すべてのケースで同じなしバッファされたストリームます。
ois = new ObjectInputStream(new BufferedInputStream(new GZIPInputStream(fis)));
oos = new ObjectOutputStream(new BufferedOutputStream(new GZIPOutputStream(fos)));
バッファされたストリームの周りのgzipストリームがわずかに優れていると - がの、テキストとストレートバイトストリームのために、私はそれがアップ投げることを見出しました。しかし、その後がないバッファされたストリームのすべての例では、より良います。
reader = new InputStreamReader(new GZIPInputStream(new BufferedInputStream(fis)));
writer = new OutputStreamWriter(new GZIPOutputStream(new BufferedOutputStream(fos)));
私は、各バージョンを20回実行し、最初の実行を遮断し、残りを平均しました。私も試してみました、バッファ-gzipでバッファリングされたテキストのために少しのオブジェクトのためのより良いと悪化しました。私はすべてのバッファサイズで再生できませんでした。
<時間>は、オブジェクトストリームの場合、私はメガバイトの10Sに2つのシリアライズされたオブジェクトファイルをテストしました。大きなファイル(38メガバイト)の場合は、85%(0.7 5.6対秒)を読んで速いけど(5.9 5.7対秒)を書き込むため、実際に少し遅かったです。これらのオブジェクトは、より大きな書き込みを意味している可能性があり、それらの一部の大きな配列を持っています。
method crc date time compressed uncompressed ratio
defla eb338650 May 19 16:59 14027543 38366001 63.4%
小さいファイル(18メガバイト)の場合は、読書を75%高速化(6.1秒対1.6)であったと(2.8 4.7対秒)を書くための40%高速化。それは小さな多数のオブジェクトが含まれています。
method crc date time compressed uncompressed ratio
defla 92c9d529 May 19 16:56 6676006 17890857 62.7%
<時間>
テキストリーダ/ライタのために私は64メガバイトCSVテキストファイルを使用していました。 (7.9 8.1対秒)を書き込む際緩衝ストリームの周りにGZIPストリームがわずかに速く読み出すための(1070ミリ秒対950)11%速かったと
method crc date time compressed uncompressed ratio
defla c6b72e34 May 20 09:16 22560860 63465800 64.5%
他のヒント
GZIPOutputStream すでに内蔵のバッファーが付属しています。だから、チェーン内の右横になBufferedOutputStreamを置く必要はありません。 gojomoの優れた答えは、すでにバッファを配置する場所にいくつかのガイダンスを提供しています。
GZIPOutputStreamのデフォルトのバッファサイズは512バイトであるので、あなたは、コンストラクタのパラメータを経由して8K、あるいは64Kに増やしたいと思うでしょう。なBufferedOutputStreamのデフォルトのバッファサイズはデフォルトGZIPOutputStreamとなBufferedOutputStreamを組み合わせたときに優位性を測定することができる理由です8K、です。その利点も適正にGZIPOutputStreamの内蔵バッファのサイズを設定することによって達成することができます。
だから、あなたの質問に答えるために:「?私は全くなBufferedOutputStreamを使用すべき」<全角> のノー→、あなたのケースでは、あなたはそれを使用するべきではありませんが、代わりに少なくとも8KにGZIPOutputStreamのバッファを設定します。
データの究極の目的地は、あなたのコードがそうでなければ、それをプッシュするよりも、より大きな塊に書かれた最高のリード/ときにバッファリングができます。だから、一般的にバッファリングが行わ-ことが-たい-大塊に近いようにしたいです。あなたの例では、それは「...」省略さ、そうGzipOutputStreamとなBufferedOutputStreamを包みました。そして、先に最高の作品を示してどのようなテストマッチするチューンなBufferedOutputStreamバッファサイズ。
私は外になBufferedOutputStreamは、明示的なバッファリングの上に、非常に、すべての場合に役立つことはないだろう。何故なの? GzipOutputStreamは、外部のバッファが存在するかどうか、同じサイズのチャンクで「...」への書き込み()の操作を行います。だから、何のための最適化「...」可能性はありません。あなたは()のGzipOutputStream書き込みのサイズ何で立ち往生しています。
また、あなたが圧縮されたデータではなく、非圧縮データをバッファリングすることで、より効率的にメモリを使用していることに注意してください。あなたのデータは、多くの場合、6X圧縮をacheives場合は、「内部の」バッファは大きなとして「外」バッファ6Xと同等です。
通常は、OSと頻繁にディスクアクセスにあまりにも多くのコールを避けるために、(それが...何を表すかだと仮定して)あなたのFileOutputStreamに近いバッファをしたいです。あなたはGZIPOutputStreamに小さな塊をたくさん書いている場合は、あなたにもGZIPOS周りのバッファの恩恵を受ける可能性があります。 GZIPOSでの書き込み方法であることの理由は、同期され、また、いくつかの他の同期呼び出しとネイティブのカップル(JNI)の呼び出し(CRC32を更新し、実際の圧縮を行うために)につながります。これらはすべて、呼び出しごとに余分なオーバーヘッドを追加します。だから、その場合には、私はあなたが両方のバッファの恩恵を受けるだろうと思います。
私はあなたはそれが大きなファイルを圧縮し、それが大きな違いを作るかどうかを確認するために取るどのくらいの時間に簡単なベンチマークを試してみてください示唆しています。 GzipOutputStreamは、バッファリングを持っていませんが、それは小さなバッファです。私は64Kのバッファーで最初に行うだろうが、あなたは両方をやっては優れていることがあります。
Javadocを読んで、あなたはBISは、いくつかのオリジナルのソースから読み込まれたバイトをバッファするために使用されていることを発見するでしょう。あなたは生のバイトを取得したら、あなたはGISでBISを包むように、それらを圧縮します。 1はそれを行うために起こっているバッファリングGZIP、についてどう思いする必要があるため、それは、GZIPからの出力をバッファリングしても意味がありません?
new GzipInputStream( new BufferedInputStream ( new FileInputXXX