Domanda

Qualcuno può consigliare se devo fare qualcosa di simile:

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

o

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

Che è più efficiente?Devo usare BufferedOutputStream a tutti?

È stato utile?

Soluzione

  

Che fine devo usare GzipOutputStream e BufferedOutputStream

Per i flussi di oggetti, ho scoperto che avvolgendo il flusso tamponato intorno al torrente gzip sia per input e l'output era quasi sempre significativamente più veloce. Il più piccolo degli oggetti, tanto meglio questo fatto. Migliore o lo stesso in tutti i casi poi alcun flusso tamponata.

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

Tuttavia , per il testo e flussi di byte dritto, ho scoperto che si trattava di una scossa in su - con il flusso di gzip intorno al torrente tamponata essendo solo leggermente migliore. Ma meglio in tutti i casi poi alcun flusso tamponata.

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

Ho eseguito ogni versione 20 volte e tagliare la prima esecuzione e una media di tutto il resto. Ho anche provato tamponata-gzip-buffered che era leggermente migliore per gli oggetti e peggio per il testo. Non ho giocato con dimensioni del buffer a tutti.


Per i corsi d'acqua oggetto, ho provato 2 file oggetto serializzato nei 10s di megabyte. Per il file più grande (38MB), era 85% più veloce a leggere (0,7 rispetto a 5,6 secondi), ma in realtà leggermente più lento per la scrittura (5,9 rispetto a 5,7 secondi). Questi oggetti hanno avuto alcune grandi array in esse, che possono aver comportato scritture più grandi.

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

Per il file più piccolo (18MB), è stato più veloce del 75% per la lettura (1,6 rispetto a 6,1 secondi) e il 40% più veloce per la scrittura (2,8 rispetto a 4,7 secondi). Conteneva un gran numero di piccoli oggetti.

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

Per il testo di lettura / scrittura che ho usato un file di testo csv 64mb. Il flusso gzip intorno al torrente tamponata è stato più veloce dell'11% per la lettura (950 contro 1.070 millisecondi) e leggermente più veloce quando si scrive (7,9 rispetto a 8,1 secondi).

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

Altri suggerimenti

GZIPOutputStream già dotato di un buffer integrato. Quindi, non c'è bisogno di mettere un BufferedOutputStream proprio accanto ad esso nella catena. risposta eccellente del gojomo fornisce già alcune indicazioni su dove posizionare il buffer.

La dimensione del buffer di default per GZIPOutputStream è solo 512 byte, così si vuole aumentarlo fino a 8K o addirittura 64K tramite il parametro del costruttore. La dimensione del buffer predefinita per BufferedOutputStream è 8K, motivo per cui si può misurare un vantaggio quando si associa il difetto GZIPOutputStream e BufferedOutputStream. Tale vantaggio può essere ottenuto anche dimensionando opportunamente tampone incorporata del GZIPOutputStream.

Quindi, per rispondere alla tua domanda: "? Dovrei usare BufferedOutputStream affatto" → No, nel tuo caso, non si dovrebbe usare, ma invece impostare il buffer della GZIPOutputStream ad almeno 8K.

Il buffer aiuta quando la destinazione finale dei dati è migliore lettura / scritta in blocchi più grandi che il vostro codice sarebbe altrimenti spingerlo. Quindi, in genere si desidera che il buffer di essere il più vicino al luogo-che-vuole--pezzi più grandi. Nei tuoi esempi, questo è il eliso "...", in modo da avvolgere il BufferedOutputStream con l'GZIPOutputStream. E, regolare la dimensione del buffer BufferedOutputStream per abbinare quello testare spettacoli funziona meglio con la destinazione.

Dubito che il BufferedOutputStream sulla parte esterna aiuterebbe molto, se non del tutto, su un periodo non buffer esplicito. Perchè no? Il GZIPOutputStream farà del suo write () s a "..." nelle stesse dimensioni pezzi se il buffer esterno è presente o meno. Quindi non c'è ottimizzazione per "..." possibile; sei bloccato con quello che dimensioni GZIPOutputStream write () s.

Si noti anche che si sta utilizzando la memoria in modo più efficiente il buffering dei dati compressi piuttosto che i dati non compressi. Se i dati acheives spesso la compressione 6X, il buffer 'dentro' è equivalente a un buffer 'fuori' 6X grande.

In genere si desidera un buffer vicino al tuo FileOutputStream (supponendo che è quello che ... rappresenta) per evitare troppe chiamate verso il sistema operativo e l'accesso al disco frequenti. Tuttavia, se si sta scrivendo un sacco di piccoli pezzi al GZIPOutputStream si potrebbe trarre beneficio da un buffer intorno GZIPOS pure. Il motivo è il metodo di scrittura nel GZIPOS è sincronizzato e porta anche ad alcune altre chiamate sincronizzati e un paio di nativo (JNI) chiama (per aggiornare il CRC32 e fare la compressione effettiva). Questi tutti aggiungere spese generali supplementari per ogni chiamata. Quindi, in questo caso direi che potrai beneficiare di entrambi i buffer.

Vi suggerisco di provare un punto di riferimento semplice per il tempo quanto tempo ci vuole per comprimere un file di grandi dimensioni e vedere se fa molta differenza. GZIPOutputStream ha buffer ma è un buffer più piccolo. Vorrei fare il primo con un buffer di 64 KB, ma si potrebbe scoprire che fare entrambe è meglio.

Leggi il javadoc, e scoprirete che il BIS è utilizzato per il buffer di byte letti da qualche fonte originale.Una volta a ottenere il raw byte che si desidera comprimere in modo di avvolgere il BIS con un GIS.Non ha senso il buffer di uscita da una GZIP, perché uno deve pensare a che cosa circa il buffering GZIP, che sta andando a fare che ?

new GzipInputStream( new BufferedInputStream ( new FileInputXXX
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top