如何减少GZIPOutputStream的时间

时间:2019-05-06 11:35:46

标签: java gzip gzipoutputstream

我试图gzip一个大的(100mb至500mb)xml文件。我创建了Zip方法来做到这一点。问题是它要花费太多时间来压缩zip.for 200mb需要1.2秒。我需要将100mb xml文件的时间也减少100毫秒。 我如何优化以减少压缩时间?

我几乎没有压缩压缩率,从而减少了时间。 尝试了另一种算法,如Snappy,Lz4,但没有太大改进,而且压缩性能也很差。据我所知gzipOutputStream.write()花费了85%的时间。压缩率。

/project/rcn/text()

1 个答案:

答案 0 :(得分:1)

这是我的建议:

  1. 创建适当的基准,以便获得可重复的结果。我建议使用基准框架。例如JMH。

  2. 分析您的代码/基准以确定瓶颈/热点在哪里;例如使用jVisualVM或Java Mission Control Flight Recorder。

  3. 使用基准测试和分析结果来指导您的优化工作。

(出于各种原因,我不会简单地依赖对System.currentTimeMillis()的调用。)

一种可能的解释是,以下步骤中有很大一部分时间用于数据复制。

  • 创建包含XML的输入字符串
  • 捕获ByteArrayOutputStream中的压缩字节
  • 将字节合并到另一个字符串中。

因此,如果您正在寻找改善此问题的方法,请尝试进行安排,以使XML序列化程序写入通过gzip和base64转换流式传输数据的管道,然后直接写入文件或套接字流。

此外,如果可能,我会避免使用base64。如果压缩的XML在HTTP响应中,则您应该能够以二进制形式发送它。它将更快,并产生更少的网络流量。

最后,选择一种可以在压缩率和压缩时间之间取得良好折衷的压缩算法。


  

如何在不影响压缩率的情况下优化此步骤以获得更好的性能。

如果您尝试这样做,您的目标可能是错误的。 (然后您为什么要对Base64编码压缩文件?这与您的目标相矛盾!)


更新以解决您的评论:

  1. (我认为)通过流传输,比将XML转换为String然后在其上调用getBytes()可获得更好的性能。首先,getBytes()调用会不必要地复制字符串内容。

  2. Lossless Compression上的Wikipedia页面链接到许多算法,其中许多算法应具有易于使用的Java实现。此外,它还具有许多基准的链接。我没有看过基准链接,但我希望至少有一个可以量化不同算法的压缩与计算时间的权衡。

  3. 如果将数据库表从CLOB更改为BLOB:

    • 您可以省去base64,节省约25%的存储空间
    • 您可以省去base64编码步骤,从而节省了百分之几的CPU
    • 然后,您可以选择更快(但不那么紧凑)的算法,从而节省了更多时间,而这是通过转到BLOB节省的部分空间的。
  4. “我不能真正改变它的业务要求。” -真的吗?如果数据库模式是业务需求,那么您的业务确实有些混乱。另一方面,如果企业在那个级别决定技术,那么他们也在决定性能。

    没有充分的技术理由将压缩数据存储为CLOB。

  5. 正如某人指出的那样,获得更快压缩的最简单方法是购买更快的计算机。或者(我的想法)是一堆计算机,以便您可以并行压缩多个文件。