Question

Quelqu'un peut-il recommander si je devrais faire quelque chose comme:

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

ou

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

Ce qui est plus efficace? Dois-je utiliser BufferedOutputStream du tout?

Était-ce utile?

La solution

  

Dans quel ordre dois-je utiliser GzipOutputStream et BufferedOutputStream

Pour les flux d'objets, je trouve que enveloppant le flux tampon autour du flux gzip pour l'entrée et la sortie était presque toujours de manière significative plus rapide. Plus les objets, mieux ce fait. Mieux ou même dans tous les cas alors pas de flux en mémoire tampon.

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

Cependant , pour le texte et les flux d'octets droites, je trouve que c'était un toss - avec le flux gzip autour du flux tampon étant légèrement mieux. Mais mieux dans tous les cas, alors pas de flux en mémoire tampon.

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

J'ai couru chaque version 20 fois et coupé la première manche et moyennées le reste. J'ai aussi essayé tampon tampon gzip, ce qui était un peu mieux pour les objets et pire encore pour le texte. Je ne joue pas avec la taille des tampons du tout.


Pour les flux d'objets, j'ai testé 2 fichiers objet sérialisé dans les 10s de méga-octets. Pour le fichier plus grand (38MB), il était de 85% plus rapide à la lecture (0,7 contre 5,6 secondes), mais en fait un peu plus lent pour l'écriture (5,9 contre 5,7 secondes). Ces objets avaient quelques grands tableaux en eux qui peuvent avoir entraîné un plus grand écrit.

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

Pour le fichier plus petit (18 Mo), il était de 75% plus rapide pour la lecture (1,6 contre 6,1 secondes) et 40% plus rapide pour l'écriture (2,8 contre 4,7 secondes). Il contenait un grand nombre de petits objets.

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

Pour le lecteur texte / auteur j'ai utilisé un fichier texte 64mb csv. Le courant de gzip autour du courant du tampon était de 11% plus rapide pour la lecture (950 par rapport à 1070 millisecondes) et légèrement plus rapide lors de l'écriture (7,9 contre 8,1 secondes).

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

Autres conseils

GZIPOutputStream vient déjà avec un tampon intégré. Donc, il n'y a pas besoin de mettre un BufferedOutputStream juste à côté de la chaîne. excellente réponse de gojomo donne déjà une idée sur l'endroit où placer le tampon.

La taille de la mémoire tampon par défaut pour GZIPOutputStream est seulement 512 octets, de sorte que vous voulez augmenter 8K ou même 64K via le paramètre constructeur. La taille de la mémoire tampon par défaut pour BufferedOutputStream est 8K, ce qui est la raison pour laquelle vous pouvez mesurer un avantage lorsque l'on combine la valeur par défaut GZIPOutputStream et BufferedOutputStream. Cet avantage peut également être réalisé par correctement le dimensionnement du tampon intégré du GZIPOutputStream.

Alors, pour répondre à votre question: « ? Dois-je utiliser BufferedOutputStream du tout » → Non, dans votre cas, vous ne devriez pas l'utiliser, mais à la place au tampon du GZIPOutputStream moins 8K.

La mise en mémoire tampon aide lorsque la destination finale des données est meilleure lecture / écrit en plus gros morceaux que votre code serait par ailleurs pousser. Donc, vous voulez généralement la mise en mémoire tampon soit aussi proche de l'endroit qui-veut-plus grand morceaux. Dans vos exemples, c'est le élidée « ... », donc envelopper le BufferedOutputStream avec le GzipOutputStream. Et, régler la taille du tampon BufferedOutputStream pour correspondre à ce test montre fonctionne mieux avec la destination.

Je doute que BufferedOutputStream à l'extérieur aiderait beaucoup, voire pas du tout, pas plus explicite en mémoire tampon. Pourquoi pas? Le GzipOutputStream fera de son écriture () s à « ... » dans les morceaux de même taille que la mise en mémoire tampon extérieur est présent ou non. Il n'y a donc pas d'optimisation pour « ... » possible; vous êtes coincé avec ce que les tailles GzipOutputStream write () s.

Notez également que vous utilisez la mémoire plus efficace en mémoire tampon des données compressées plutôt que les données non compressées. Si vos données acheives souvent la compression 6X, le tampon « intérieur » est équivalent à un tampon « extérieur » 6X aussi grand.

Normalement, vous voulez un tampon proche de votre FileOutputStream (en supposant que est ce que ... représente) pour éviter un trop grand nombre d'appels dans le système d'exploitation et l'accès disque fréquents. Toutefois, si vous écrivez beaucoup de petits morceaux au GZIPOutputStream vous pourriez bénéficier d'une zone tampon autour GZIPOS ainsi. La raison étant la méthode d'écriture dans GZIPOS est synchronisé et conduit également à quelques autres appels synchronisés et un couple de natif (JNI) appelle (mettre à jour le CRC32 et faire la compression réelle). Ceux-ci ajoutent tous les frais généraux supplémentaires par appel. Donc, dans ce cas, je dirais que vous bénéficierez des deux tampons.

Je vous suggère d'essayer une référence simple à temps combien de temps il pour compresser un fichier volumineux et voir si cela fait beaucoup de différence. GzipOutputStream n'ont en mémoire tampon, mais il est un petit tampon. Je ferais la première avec un tampon 64K, mais vous pourriez trouver que faire deux est mieux.

Lire la javadoc, et vous découvrirez que BIS est utilisé pour tamponner octets lus à partir d'une source d'origine. Une fois que vous obtenez les octets bruts que vous voulez les compresser pour vous envelopper BIS avec un SIG. Il ne fait aucun sens de tamponner la sortie d'un GZIP, car il faut penser à propos de ce GZIP tampon, qui va le faire?

new GzipInputStream( new BufferedInputStream ( new FileInputXXX
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top