首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我应该按什么顺序使用GzipOutputStream和BufferedOutputStream

我应该按什么顺序使用GzipOutputStream和BufferedOutputStream
EN

Stack Overflow用户
提问于 2009-07-04 14:41:05
回答 6查看 16.1K关注 0票数 30

有没有人可以推荐我是否应该这样做:

代码语言:javascript
复制
os = new GzipOutputStream(new BufferedOutputStream(...));

代码语言:javascript
复制
os = new BufferedOutputStream(new GzipOutputStream(...));

哪一个更有效率?我应该使用BufferedOutputStream吗?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-05-20 06:12:39

我应该按什么顺序使用GzipOutputStreamBufferedOutputStream

对于对象流,我发现在输入和输出的gzip流周围包装缓冲流几乎总是要快得多。对象越小,效果就越好。在所有情况下都比没有缓冲流更好或相同。

代码语言:javascript
复制
ois = new ObjectInputStream(new BufferedInputStream(new GZIPInputStream(fis)));
oos = new ObjectOutputStream(new BufferedOutputStream(new GZIPOutputStream(fos)));

但是,对于文本流和纯字节流,我发现这是一个很难解决的问题--缓冲流周围的gzip流只稍微好一点。但在所有情况下都比没有缓冲流要好。

代码语言:javascript
复制
reader = new InputStreamReader(new GZIPInputStream(new BufferedInputStream(fis)));
writer = new OutputStreamWriter(new GZIPOutputStream(new BufferedOutputStream(fos)));

我将每个版本运行了20次,并截断了第一次运行,然后对其余的运行进行了平均。我还尝试了buffered-gzip-buffered,它对对象稍好一些,对文本则更差一些。我根本没有使用缓冲区大小。

对于对象流,我测试了两个大小为10兆字节的序列化对象文件。对于较大的文件(38mb),读取速度快了85% (0.7秒对5.6秒),但实际上写入速度略慢(5.9秒对5.7秒)。这些对象中有一些大的数组,这可能意味着更大的写入。

代码语言:javascript
复制
method       crc     date  time    compressed    uncompressed  ratio
defla   eb338650   May 19 16:59      14027543        38366001  63.4%

对于较小的文件(18mb),读取速度快75% (1.6秒对6.1秒),写入速度快40% (2.8秒对4.7秒)。它包含了大量的小物体。

代码语言:javascript
复制
method       crc     date  time    compressed    uncompressed  ratio
defla   92c9d529   May 19 16:56       6676006        17890857  62.7%

对于文本阅读器/写入器,我使用了64mb的csv文本文件。缓冲流周围的gzip流读取速度快11% (950vs1070毫秒),写入速度略快(7.9vs8.1秒)。

代码语言:javascript
复制
method       crc     date  time    compressed    uncompressed  ratio
defla   c6b72e34   May 20 09:16      22560860        63465800  64.5%
票数 30
EN

Stack Overflow用户

发布于 2013-09-26 23:30:12

GZIPOutputStream已经提供了一个内置的buffer。因此,没有必要在链中将BufferedOutputStream放在它的旁边。gojomo的出色回答已经提供了一些关于在何处放置缓冲区的指导。

GZIPOutputStream的默认缓冲区大小只有512字节,因此您需要通过构造函数参数将其增加到8K甚至64K。BufferedOutputStream的默认缓冲区大小是8K,这就是在组合默认GZIPOutputStream和BufferedOutputStream时可以衡量优势的原因。这一优势也可以通过适当调整GZIPOutputStream的内置缓冲区大小来实现。

所以,为了回答你的问题:“我应该使用BufferedOutputStream吗?”→不,在你的例子中,你不应该使用它,而是将GZIPOutputStream的缓冲区设置为至少8K。

票数 30
EN

Stack Overflow用户

发布于 2009-07-04 22:49:38

当数据的最终目标以更大的块进行读/写,而不是代码推送它时,缓冲会有所帮助。因此,您通常希望缓冲区尽可能靠近想要更大块的位置。在您的示例中,这是省略的"...",所以用GzipOutputStream包装BufferedOutputStream。并且,调整BufferedOutputStream缓冲区大小,以匹配测试显示的最适合目的地的内容。

我怀疑在没有显式缓冲的情况下,外部的BufferedOutputStream是否会有很大帮助。为什么不行?GzipOutputStream将对"...“执行写入()操作。在相同大小的块中,无论是否存在外部缓冲。所以没有针对"...“的优化有可能;您会遇到GzipOutputStream write()的大小问题。

还请注意,通过缓冲压缩数据而不是未压缩数据,您可以更有效地使用内存。如果你的数据经常达到6倍的压缩,那么“内部”缓冲区相当于“外部”缓冲区的6倍大小。

票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1082320

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档