GZIPOutputStream与BufferedOutputStream的性能

时间:2017-09-04 01:25:43

标签: java gzipoutputstream bufferedoutputstream

我的应用程序正在尽可能快地将大量视频和i2c传感器数据记录到磁盘文件中。目前我正在将所有内容转换为字节,我正在使用BufferedOutputStream进行编写。 @Siguza非常友好地建议调查GZIPOutputStream以完成契约。我想知道你是否有任何关于性能问题的想法pro和con ...我认为处理器领先,磁盘写入是瓶颈 - 所以我希望在写入之前通过GZIPOutputStream动态压缩一个好的策略。对此的任何想法都非常欢迎。

补充:回应评论......

事实证明,拉链并不是那种昂贵的处理器...而且我问过原始问题的方式并不是很好,正如erwin正确地指出的那样。关于压缩性能的问题不在BufferedOutputStream和GZIPOutputStream之间......压缩和解压缩的流都需要包装到BufferedOutputStream中,但如果原始的FileOutputStream先包装在GZIPOutputStream中,那么会增加多少成本包装在BufferedOutputStream中。这是答案。我正在使用代码

byte[] bs = RHUtilities.toByteArray((int)1);
boolean zipped = false;

FileOutputStream fos = new FileOutputStream(datFile);
BufferedOutputStream bos = null;
if (zipped) {
    GZIPOutputStream gz = new GZIPOutputStream(fos);
    bos = new BufferedOutputStream(gz);
} else 
    bos = new BufferedOutputStream(fos);
long startT = System.currentTimeMillis();
for (int i=0; i<1000000; i++)
    bos.write(bs);
bos.flush();
System.out.println(System.currentTimeMillis()-startT);
bos.close();

我的2012 macpro笔记本电脑用

写了1M整数

压缩= 38毫秒时为真 - 文件大小为4MB
zipped = 21ms内的false - fileSize 4KB

并且,是的,我喜欢压缩: - )

读取性能几乎相同83对86ms之间

FileInputStream fin = new FileInputStream(datFile);

GZIPInputStream gin = new GZIPInputStream(new FileInputStream(datFile));
一切都很好......

1 个答案:

答案 0 :(得分:1)

这个问题提出了很多问题:

  

我认为处理器领先,磁盘写入是瓶颈

&#34;我在想&#34;优化性能不是一个合理的基础。您需要进行一些测量以找出瓶颈的实际位置。 (如果你的思维错误,那么改为GZipOutputStream可能会让事情变得更糟。)

或者,只需尝试一下,衡量是否可以提高性能。

从理论角度来看,如果处理器和光盘速度之间存在显着的不匹配,那么压缩可能有所帮助。一个可能的好处是压缩也可以节省磁盘空间。

但缺点是:

  • 压缩相对较贵(解压缩也是如此),因此您最终可能会使用比通过减少I / O获得的更多(经过)时间
  • 压缩对小文件无效,
  • 格式不可知压缩对原始(未压缩)音频或视频数据 1
  • 不是很有效
  • 如果您的视频数据已经过压缩,则第二次压缩将无法实现。

最后,它可能是一个&#34;许多小文件&#34;问题。如果您尝试读取和写入大量小文件,则瓶颈可能不是原始磁盘速度。相反,它可能是操作系统读取和写入目录和/或文件元数据的能力。如果这就是您的问题所在,那么您应该考虑捆绑许多小文件&#34;进入档案馆;例如TAR或ZIP文件。有用Java的库。

档案的另一个好处是它们可以使压缩更有效。

1 - 有关背景信息,请阅读https://en.wikipedia.org/wiki/Lossless_compressionhttps://en.wikipedia.org/wiki/List_of_codecs#Lossless_video_compression