У меня есть приложение .NET 2.0 WinForms, которое подключается к серверу WAS. Я использую GZipStream для декодирования данных, возвращающихся из обращения HttpWebRequest к серверу. Возвращаемые данные представляют собой сжатый CSV, который Apache сжимает. Весь стек сервера - Hibernate -> EJB -> Spring -> Apache.GZipStream производительность декомпрессии плохая
Для небольших откликов производительность отличная (< 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();
}
}
}
Edit 1
Основываясь на комментарий от Лусеро, я изменил метод 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();
}
}
}
}
На основании вышеизложенного кода могут ли возникнуть какие-либо проблемы? Для меня это кажется довольно основным, но это заставляет меня сходить с ума.
Edit 2
Я профилированный приложение с помощью ANTS Profiler, и в течение 60-х годов декомпрессией, процессор близок к нулю, а использование памяти не меняется.
Редактировать 3
Фактическое замедление, как представляется, во время чтения из
this.Response.GetResponseStreamThe целых 60-х затрачивается загрузки поток ответа в MemoryStream. Как только он там, звонок в GZipStream выполняется быстро.
Edit 4
Я обнаружил, что использование HttpWebRequest.AutomaticDecompression имеет тот же вопрос производительности, поэтому я закрываю этот вопрос.
Голосование, чтобы закрыть, потому что декомпрессия не является правильным вопросом. – Armbrat
Когда вы говорите, что добавление потока памяти не улучшило производительность, вы фактически измеряете время, которое требуется, чтобы закрепить отдельно от времени, необходимого для записи всего ответа на поток памяти? Мое подозрение заключается в том, что процессор близок к нулю, что узкое место не является застежкой, но насколько быстро вы можете загрузить ответ. –
Вы решили эту проблему? – rolls