2009-10-05 96 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