簡體   English   中英

如何提高GZIP性能

[英]How to improve GZIP performance

目前,我確實有一個問題,這段代碼將被調用> 500k次。 壓縮后的byte[]大小小於1KB。 每次調用該方法時,都必須創建所有流。 因此,我正在尋找一種改進此代碼的方法。

private byte[] unzip(byte[] data) throws IOException, DataFormatException {

    byte[] unzipData = new byte[4096];

    try (ByteArrayInputStream in = new ByteArrayInputStream(data);
         GZIPInputStream gzipIn = new GZIPInputStream(in);
         ByteArrayOutputStream out = new ByteArrayOutputStream()) {

        int read = 0;
        while( (read = gzipIn.read(unzipData)) != -1) {
            out.write(unzipData, 0, read);
        }

        return out.toByteArray();
    }
}

我已經嘗試ByteBuffer替換ByteArrayOutputStream ,但是在創建時我不知道需要分配多少字節。

另外,我嘗試使用Inflater但偶然發現了此處描述的問題。

任何其他想法,我可以做些什么來改善此代碼的性能。

更新#1

  • 也許這個 lib可以幫助某人。
  • 也有一個開放的JDK-Bug
  1. 分析您的應用程序,以確保您確實在此功能上花費了可優化的時間。 調用該函數多少次無關緊要; 如果它在整個程序執行時間中所占的比例不大,那么優化就浪費了。

  2. 調整ByteArrayOutputStream的大小。 默認緩沖區大小為32個字節,並且調整大小要求復制所有現有字節。 如果您知道解碼后的數組大約為1k,請使用new ByteArrayOutputStream(2048)

  3. 使用預先分配的byte[]一次讀取一個塊,而不是一次讀取一個字節。 注意,必須使用read的返回值作為write的輸入。 最好使用Jakarta Commons IOUtils.copy()之類的東西來避免錯誤。

我不確定它是否適用於您的情況,但是使用默認的GZIPInputStream緩沖區大小與增加到65536進行比較時,發現速度差異非常大。

示例:使用500M輸入文件->

new GZIPInputStream(new FileInputStream(path.toFile())) // takes 4 mins to process

VS

new GZIPInputStream(new FileInputStream(path.toFile()), 65536) // takes 10s

Ĵ

可以在這里找到更多詳細信息http://java-performance.info/java-io-bufferedinputstream-and-java-util-zip-gzipinputstream/

BufferedInputStream和GZIPInputStream都有內部緩沖區。 前一個的默認大小為8192字節,而后一個的默認大小為512字節。 通常值得將這些大小中的任何一個增加到至少65536。

您可以使用Inflater類方法reset()重用Inflater對象,而不必每次都重新創建它。 您將需要做一些額外的編程工作,以便解碼gzip標頭並使用gzip預告片執行完整性檢查。 然后,您可以將Inflaternowrap選項一起使用,以在gzip標頭之后和預告片之前解壓縮原始的壓縮數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM