У меня есть приложение .NET 2.0 WinForms, которое подключается к внутреннему WAS-серверу. Я использую GZipStream для декодирования данных, возвращающихся из вызова HttpWebRequest на сервер. Возвращенные данные являются сжатыми CSV, которые Apache сжимает. Весь стек сервера находится в Hibernate -> EJB -> Spring -> Apache.
Для небольших ответов производительность в порядке (<50 мс). Когда я получаю ответ> 150 КБ, требуется более 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
Исходя из комментария от Lucero, я изменил метод Decompress следующим образом, но я не вижу какого-либо выигрыша в производительности от загрузки ResponseStream в MemoryStream до создания экземпляра GZipStream.
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 Profiler, и в течение 60-х годов декомпрессии ЦП приближался к нулю и использование памяти не менялось.
Редактировать 3
Фактическое замедление происходит во время чтения
this.Response.GetResponseStream
Все 60 секунд тратятся на загрузку потока ответов в MemoryStream. Как только он появится, вызов GZipStream будет быстрым.
Редактировать 4
Я обнаружил, что при использовании HttpWebRequest.AutomaticDecompression возникает та же проблема с производительностью, поэтому я закрываю этот вопрос.