gpt4 book ai didi

java - 如何减少 GZIPOutputStream 的时间

转载 作者:行者123 更新时间:2023-11-30 05:39:17 26 4
gpt4 key购买 nike

我尝试过 gzip 一个大的(100mb 到 500mb)xml 文件。我已经创建了方法 Zip 来做到这一点。问题是它的 zip 时间太多了。对于 200mb 的文件,需要 1.2 秒。对于 100mb 的 xml 文件,我需要将时间减少 100 毫秒。如何优化以减少压缩时间?

我通过在压缩比上做出一点妥协来减少时间。尝试了其他算法,如 Snappy、Lz4,但没有太大改进,而且它们的压缩率也很差。据我所知,gzipOutputStream.write() 需要 85% 的时间。那么我如何优化此步骤以获得更好的性能而不影响大部分压缩比。

public static String zip(final String str) {
if ((str == null) || (str.length() == 0)) {
throw new IllegalArgumentException("Cannot zip null or empty string");
}

try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(str.length())) {
try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream){{def.setLevel(Deflater.BEST_SPEED );}};) {
gzipOutputStream.write(str.getBytes(StandardCharsets.UTF_8));

}
T5 = System.currentTimeMillis();
byte[] bytes=byteArrayOutputStream.toByteArray();
T3 = System.currentTimeMillis();

String zipped_text=DatatypeConverter.printBase64Binary(bytes);
T4 = System.currentTimeMillis();
return zipped_text;

} catch(IOException e) {
throw new RuntimeException("Failed to zip content", e);
}

}

最佳答案

这是我的建议:

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

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

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

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

一种可能的解释是,很大一部分时间花费在以下步骤中的数据复制上。

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

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

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

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

<小时/>

How can I optimize this step to get better performance with out compromising the compression ratio.

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

<小时/>

针对您的评论进行更新:

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

  2. 维基百科页面Lossless Compression链接到许多算法,其中许多应该有现成的 Java 实现。此外,它还链接到许多基准测试。我还没有查看基准测试链接,但我希望至少有一个能够量化不同算法的压缩与计算时间之间的权衡。

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

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

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

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

关于java - 如何减少 GZIPOutputStream 的时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56004422/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com