2009-10-05 92 views
3

我有一個連接到後端WAS服務器的.NET 2.0 WinForms應用程序。我正在使用GZipStream解碼從服務器發出的HttpWebRequest調用返回的數據。返回的數據是壓縮的CSV,這是Apache正在壓縮的。整個服務器堆棧是Hibernate - > EJB - > Spring - > Apache。GZipStream解壓縮性能差

對於小的響應,性能很好(< 50ms)。當我獲得大於150KB的響應時,需要60秒以上才能解壓縮。大部分時間似乎都花在GZipStream的構造函數中。

這是代碼表示從哪裏獲得從HttpWebResponse呼叫響應流:

using (Stream stream = this.Response.GetResponseStream()) 
{ 
if (this.CompressData && this.Response.ContentEncoding == "gzip") 
{ 
     // Decompress the response 
    byte[] b = Decompress(stream); 
    this.ResponseBody = encoding.GetString(b); 
    } 
else 
{ 
    // Just read the stream as a string 
    using (StreamReader sr = new StreamReader(stream)) 
    { 
    this.ResponseBody = sr.ReadToEnd(); 
    } 
} 
} 

編輯1

基於來自盧塞羅註釋,我修改瞭解壓縮方法,以下面的,但是在實例化GZipStream之前,我沒有看到將ResponseStream加載到MemoryStream中帶來的任何性能優勢。

private static byte[] Decompress(Stream stream) 
{ 
using (MemoryStream ms = new MemoryStream()) 
{ 
    byte[] buffer = new byte[4096]; 
    int read = 0; 

    while ((read = stream.Read(buffer, 0, buffer.Length)) > 0) 
    { 
    ms.Write(buffer, 0, read); 
    } 

    ms.Seek(0, SeekOrigin.Begin); 

    using (GZipStream gzipStream = new GZipStream(ms, CompressionMode.Decompress, false)) 
    { 
    read = 0; 
    buffer = new byte[4096]; 

    using (MemoryStream output = new MemoryStream()) 
    { 
    while ((read = gzipStream.Read(buffer, 0, buffer.Length)) > 0) 
    { 
    output.Write(buffer, 0, read); 
    } 

    return output.ToArray(); 
    } 
    } 
} 
} 

根據上面的代碼,任何人都可以看到任何問題嗎?這對我來說似乎很基本,但是這讓我感到非常緊張。

編輯2

予成型使用ANTS探查該應用程序,並減壓60年代期間,CPU是接近零和存儲器使用量不變化。

編輯3

實際減速似乎是

this.Response.GetResponseStream
整個60年代讀取期間花費加載響應流進MemoryStream的。一旦它在那裏,GZipStream的呼叫很快。
編輯4

我發現,使用HttpWebRequest.AutomaticDecompression出現相同的性能問題,所以我關閉了這個問題。

+0

投票關閉,因爲解壓縮不是正確的問題。 – Armbrat 2009-10-06 19:28:17

+0

當你說添加內存流並沒有提高性能時,你是否實際上測量了將整個響應寫入內存流所需的時間與分開壓縮的時間?我的懷疑是,鑑於CPU接近零,瓶頸不是壓縮,但你可以下載響應的速度有多快。 – 2014-05-26 18:38:48

+0

你解決了這個問題嗎? – rolls 2018-02-08 02:43:19

回答

1

首先嚐試將數據加載到一個MemoryStream,然後解壓縮的MemoryStream ...

+0

我試過 - 看到修改後的問題。感謝您的建議。 – Armbrat 2009-10-05 20:37:41

+0

我明白了。時間仍然在GZip流的構造函數中,還是現在在其他地方? – Lucero 2009-10-05 20:45:48

+0

這是(據我所知)花在GZip流的構造函數中。 – Armbrat 2009-10-05 21:12:19

0

對不起,沒有直接回答你的問題,但你在SharpZip看了沒有?我發現它比Gzip更容易使用。如果您在解決當前問題時遇到問題,可能會更好地執行任務。

http://www.icsharpcode.net/OpenSource/SharpZipLib/

+0

我已經嘗試過SharpZipLib,它與System.IO.Compression.GZipStream和DotNetZip一樣表現出同樣糟糕的性能。我將逐步介紹SharpZipLib源代碼,以查看是否有任何東西跳出來。 – Armbrat 2009-10-06 15:12:02

+0

有趣...我有一個大型的XML文件,這是約70兆解壓縮在系統上約15秒解壓縮。我開始懷疑它是否真的與你的代碼相關。你可以看看你係統上的Antivirus嗎?也許它掛了。我們與IBM的Etrust存在重大問題,掛起文件的時間比他們應該的要長得多。如果你喜歡,我可以提供一個代碼示例,但我認爲它不是代碼相關的。 – 2009-10-06 17:02:03

+0

我在想想還有什麼可能是你的瓶頸。您可以嘗試在該系統上運行內存測試器。也許它有一些錯誤的內存?我只是腦力激盪着你。看起來很奇怪。 – 2009-10-06 17:03:15

1

DotNetZip具有可以被用作下拉更換爲System.IO.Compression.GZipStream一個GZipStream類。

DotNetZip是免費的。

注意:如果你只是在做GZipStream,那麼你需要Ionic.Zlib.dll,而不是Ionic.Zip.dll。

+0

我嘗試使用DotNetZip/Zlib庫,但發現相同的性能問題。 – Armbrat 2009-10-05 20:32:53

+0

如果是這種情況,那麼它好像不是DeflateStream。也許你有一個記憶問題。也許你應該測試更多的迭代 - 很難根據單次迭代和單個試驗得出性能結論。 – Cheeso 2009-10-06 04:30:24

+0

我不遵循「測試更多迭代」的含義嗎?這是對同一臺服務器的許多請求之一。大多數請求只能得到〜<10k的數據。這是唯一的「大」請求,它只有〜150k。 – Armbrat 2009-10-06 12:33:09