Frage

Kann jemand empfehlen, ob ich etwas tun sollte wie:

os = new GzipOutputStream(new BufferedOutputStream(...));

oder

os = new BufferedOutputStream(new GzipOutputStream(...));

Was ist effizienter? Sollte ich BufferedOutputStream überhaupt benutzen?

War es hilfreich?

Lösung

  

Welche Reihenfolge sollte ich GzipOutputStream und BufferedOutputStream

Für Objektströme, fand ich, dass rund um den gzip Strom den gepufferten Stromes Einwickeln sowohl für Ein- und Ausgang war fast immer deutlich schneller. Je kleiner die Objekte, desto besser tat dies. Besser oder das gleiche in allen Fällen dann nicht gepufferten Strom.

ois = new ObjectInputStream(new BufferedInputStream(new GZIPInputStream(fis)));
oos = new ObjectOutputStream(new BufferedOutputStream(new GZIPOutputStream(fos)));

Jedoch , für Text und gerade Byte-Streams, fand ich, dass es einen toss war - mit dem gzip Strom um den gepufferten Strom nur wenig besser zu sein. Aber besser in allen Fällen dann nicht gepufferten Strom.

reader = new InputStreamReader(new GZIPInputStream(new BufferedInputStream(fis)));
writer = new OutputStreamWriter(new GZIPOutputStream(new BufferedOutputStream(fos)));

lief ich jede Version 20-mal und den ersten Lauf abgeschnitten und der Rest gemittelt. Ich habe auch versucht gepuffert-gzip-gepuffert, der für Objekte und schlechter für Text etwas besser war. Ich habe nicht mit Puffergrößen spielen.


Für die Objektströme getestet I 2 serialisierten Objektdateien in den 10s Megabyte. Für die größere Datei (38MB), war es 85% schneller beim Lesen (0,7 im Vergleich zu 5,6 Sekunden), aber tatsächlich etwas langsamer zum Schreiben (5,9 im Vergleich zu 5,7 Sekunden). Diese Aufgaben hatten einige große Arrays in ihnen, die größer schreibt gemeint haben.

method       crc     date  time    compressed    uncompressed  ratio
defla   eb338650   May 19 16:59      14027543        38366001  63.4%

Für die kleinere Datei (18MB), war es 75% schneller zum Lesen (1,6 im Vergleich zu 6,1 Sekunden) und 40% schneller zum Schreiben (2,8 im Vergleich zu 4,7 Sekunden). Es enthielt eine große Anzahl von kleinen Objekten.

method       crc     date  time    compressed    uncompressed  ratio
defla   92c9d529   May 19 16:56       6676006        17890857  62.7%

Für den Text-Leser / Schreiber verwendete ich eine 64mb CSV-Textdatei. Der gzip Strom um den gepufferten Strom betrug 11% schneller zum Lesen (950 im Vergleich zu 1070 Millisekunden) und etwas schneller, wenn (7,9 im Vergleich zu 8,1 Sekunden) zu schreiben.

method       crc     date  time    compressed    uncompressed  ratio
defla   c6b72e34   May 20 09:16      22560860        63465800  64.5%

Andere Tipps

GZIPOutputStream kommt bereits mit einem eingebauten Puffer. So gibt es keine Notwendigkeit, ein BufferedOutputStream direkt daneben in der Kette zu legen. gojomo die ausgezeichnete Antwort liefert bereits einige Hinweise darüber, wo die Puffer zu platzieren.

Die Standardpuffergröße für GZIPOutputStream ist nur 512 Bytes, so dass Sie es zu 8K oder sogar 64K über den Konstruktor Parameter erhöhen möchten. Die Standardpuffergröße für BufferedOutputStream ist 8K, weshalb Sie einen Vorteil messen können, wenn der Standard GZIPOutputStream und BufferedOutputStream kombinieren. Dieser Vorteil kann auch richtig erreicht werden, indem die GZIPOutputStream des eingebauten Puffer Dimensionierung.

Also, Ihre Frage zu beantworten: "? Soll ich BufferedOutputStream at all" → Nein, in Ihrem Fall, sollten Sie es nicht verwenden, sondern stattdessen den Puffer des GZIPOutputStream auf mindestens 8K.

Die Pufferung hilft, bei der das ultimative Ziel der Daten am besten Lese- / in größeren Stücken geschrieben, als der Code sonst schieben würde. So möchten Sie in der Regel die Pufferung so nah an dem Ort-that-will-größer-Brocken sein. In Ihren Beispielen ist, dass die elided „...“, so wickeln Sie das BufferedOutputStream mit dem GzipOutputStream. Und stimmt die BufferedOutputStream Puffergröße zu entsprechen, was zeigt Testen funktioniert am besten mit dem Ziel.

Ich bezweifle das BufferedOutputStream auf der Außenseite viel helfen würde, wenn überhaupt, über keine explizite Pufferung. Warum nicht? Die GzipOutputStream seine Schreib tun wird () s zu „...“ in den gleich großen Brocken, ob die Außen Pufferung vorhanden ist oder nicht. Es gibt also keine Optimierung für „...“ möglich; Sie mit stecken, welche Größen GzipOutputStream write () s.

Beachten Sie auch, dass Sie Speicher effizienter verwenden, indem die komprimierten Daten zu puffern, anstatt die unkomprimierten Daten. Wenn oft Ihre Daten Übertragungskameras 6X Kompression ist das ‚Innere‘ Puffer entspricht einem ‚außerhalb‘ Puffer 6X so groß.

Normalerweise wollen Sie einen Puffer zu Ihrer Outputstream schließen (vorausgesetzt, das ist, was ... darstellt) zu vermeiden viele Anrufe in das Betriebssystem und häufig Plattenzugriff. Wenn Sie jedoch sind viele kleine Stücke zum GZIPOutputStream Schreiben Sie könnte genauso gut von einem Puffer um GZIPOS profitieren. Der Grund dafür ist die Schreibmethode in GZIPOS synchronisiert und führt auch zu einigen anderen synchronisiert Anrufe und ein paar einheimische (JNI) aufruft (um die CRC32 zu aktualisieren und die tatsächliche Komprimierung tun). Diese alle fügen zusätzlichen Aufwand pro Anruf. Also in diesem Fall würde ich sagen, dass Sie von beiden Puffern profitieren werden.

Ich schlage vor, Sie versuchen, einen einfachen Maßstab zu Zeit, wie lange es dauern, eine große Datei zu komprimieren und sehen, ob es viel Unterschied macht. GzipOutputStream tut Pufferung, aber es ist ein kleiner Puffer. Ich würde die erste mit einem 64K-Puffer tun, aber Sie werden feststellen, dass beide es besser ist.

Lesen Sie die javadoc, und Sie werden feststellen, dass BIS verwendet wird Bytes von einer Quelle gelesen zu puffern. Sobald Sie die rohen Bytes erhalten wollen, um sie zu komprimieren, so dass Sie BIS mit einem GIS-wickeln. Es macht keinen Sinn, den Ausgang von einem GZIP zu puffern, weil man was Pufferung GZIP zu denken braucht, wer das tun wird?

new GzipInputStream( new BufferedInputStream ( new FileInputXXX
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top