我应该用什么样的顺序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的缓冲这对对象进行文字略好与差。我根本不与缓冲区大小播放。
有关的对象流,我以MB为单位的10秒测试2页序列化对象的文件。对于较大的文件(38MB),它是在阅读(0.7对5.6秒)快85%,但实际上是写入(5.9对5.7秒)稍微慢一些。这些对象在他们有一些大的阵列,其可能意味着更大的写入。
method crc date time compressed uncompressed ratio
defla eb338650 May 19 16:59 14027543 38366001 63.4%
有关的较小的文件(18MB),它是用于读出(1.6对6.1秒)和40%的速度用于写入(2.8对4.7秒)快75%。它包含大量的小物体。
method crc date time compressed uncompressed ratio
defla 92c9d529 May 19 16:56 6676006 17890857 62.7%
有关的文本阅读器/写入器我使用的64MB CSV文本文件。所缓冲的流周围gzip的流是用于读取(950与1070毫秒)快11%,略微写入(7.9对8.1秒)时更快。
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默认的缓冲区大小为8K,这就是为什么你可以结合默认GZIPOutputStream和的BufferedOutputStream时测量的优势。这种优势也可以通过适当地施胶GZIPOutputStream内置的缓冲器来实现的。
因此,要回答你的问题:“?我应该使用的BufferedOutputStream在所有” 的→不,你的情况,你不应该使用它,而是在GZIPOutputStream的缓冲区至少设置为8K。
缓冲有助于当所述数据的最终目的地是最好的读/写在更大的块比您的代码,否则其推入。所以,你一般要缓冲,以尽可能接近的地方,即,希望-较大块。在你的例子,这是消隐“...”,使包装与GzipOutputStream中的BufferedOutputStream。而且,调整的BufferedOutputStream缓冲区的大小以匹配与目标测试显示效果最好。
我怀疑在外面的BufferedOutputStream将帮助不大,如果在所有,在没有明确的缓冲。为什么不?该GzipOutputStream将尽其write()s到“......”在同一大小的块是否外侧缓冲存在或不存在。因此,有没有优化“...”成为可能;你坚持什么尺寸GzipOutputStream写()秒。
还要注意的是你更有效地利用存储器通过缓冲压缩数据,而不是未压缩数据。如果数据经常acheives 6X压缩,所述“内部”缓冲器相当于一个“外部”缓冲器6X一样大。
通常你想有一个缓冲区接近你的FileOutputStream中(假设这是什么......代表),以避免过多调用到操作系统和频繁的磁盘访问。但是,如果你写了很多小块的到GZIPOutputStream你可能会从身边GZIPOS缓冲中受益。究其原因是在GZIPOS写入方法是同步的,也导致了一些其他的同步调用和几个本地的(JNI)调用(更新CRC32和做实际的压缩)。这些都每次通话添加额外的开销。因此,在这种情况下,我会说,你会从两个缓冲区中受益。
我建议你尝试一个简单的基准时间需要多长时间来压缩大文件,并且看它是否太大的区别。 GzipOutputStream确实有缓冲,但它是一个较小的缓冲区。我会做的先用64K缓冲区,但你可能会发现,这样做既比较好。
读取的Javadoc,你会发现,BIS用于缓冲从某些原始源读取的字节。一旦你得到的原始字节,你要那么你有一个包裹GIS BIS对其进行压缩。这是没有意义缓冲从GZIP输出,因为一个需要思考的缓冲GZIP,谁是打算做什么?
new GzipInputStream( new BufferedInputStream ( new FileInputXXX