2009-10-05 3 views
3

У меня есть приложение .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.GetResponseStream
The целых 60-х затрачивается загрузки поток ответа в MemoryStream. Как только он там, звонок в GZipStream выполняется быстро.
Edit 4

Я обнаружил, что использование HttpWebRequest.AutomaticDecompression имеет тот же вопрос производительности, поэтому я закрываю этот вопрос.

+0

Голосование, чтобы закрыть, потому что декомпрессия не является правильным вопросом. – Armbrat

+0

Когда вы говорите, что добавление потока памяти не улучшило производительность, вы фактически измеряете время, которое требуется, чтобы закрепить отдельно от времени, необходимого для записи всего ответа на поток памяти? Мое подозрение заключается в том, что процессор близок к нулю, что узкое место не является застежкой, но насколько быстро вы можете загрузить ответ. –

+0

Вы решили эту проблему? – rolls

ответ

1

Попробуйте сначала загрузить данные в MemoryStream, а затем распаковывать MemoryStream ...

+0

Я пробовал это - см. Измененный вопрос. Спасибо за предложение. – Armbrat

+0

Я вижу. Является ли время еще проведенным в конструкторе потока GZip или сейчас где-то еще? – Lucero

+0

Это (насколько я могу судить), проведенное в конструкторе потока GZip. – Armbrat

0

Извините, нет ответа на ваш вопрос прямо, но вы смотрели на SharpZip еще? Мне было гораздо проще в использовании, чем Gzip. Если у вас возникнут проблемы с решением текущей проблемы, возможно, это будет лучше выполнять задачу.

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

+0

Я пробовал SharpZipLib, и он демонстрирует ту же плохую производительность, что и System.IO.Compression.GZipStream и DotNetZip. Я собираюсь пройти через источник SharpZipLib, чтобы увидеть, что-нибудь выскакивает на меня. – Armbrat

+0

Интересно ... У меня есть большой xml-файл, который составляет около 70 мегабайт без сжатия, который распаковывается примерно через 15 секунд в системе. Я начинаю задаваться вопросом, действительно ли это связано с вашим кодом. Не могли бы вы взглянуть на свой антивирус в этой системе? Возможно, он висит. У нас были серьезные проблемы с Etrust от IBM, зависающей файлами намного дольше, чем нужно. Я могу предоставить образец кода, если вам нравится, но снова я думаю, что это не связанный с кодом. –

+0

Я пытаюсь думать о том, что еще может быть вашей бутылочной шее. Вы можете попробовать запустить тестер памяти в этой системе. Может быть, у него есть неисправная оперативная память? Я просто штурмую мозги за тебя. Просто кажется странным. –

1

DotNetZip имеет класс GZipStream, который может быть использован в качестве замены для System.IO.Compression.GZipStream.

DotNetZip является бесплатным.

NB: Если вы только делаете GZipStream, вам нужен Ionic.Zlib.dll, а не Ionic.Zip.dll.

+0

Я попытался использовать библиотеку DotNetZip/Zlib, но обнаружил такую ​​же проблему с производительностью. – Armbrat

+0

Если это так, то кажется, что это не DeflateStream. Возможно, у вас проблема с памятью. Может быть, вам стоит протестировать больше итераций - сложно сделать выводы о производительности на основе единственной итерации, единого испытания. – Cheeso

+0

Я не понимаю, что вы подразумеваете под «тестировать больше итераций»? Это один из многих запросов на тот же сервер. Большинство запросов получают только данные ~ <10k. Это единственный «большой» запрос, и это всего лишь ~ 150 тыс. – Armbrat

0

Я отброшу свои три цента к теме, просто чтобы уведомить пользователей C# о том, что 7Zip, похоже, раскрывает свой API на простом C#.Я думаю, что вы все хорошо знаете инструмент 7Zip и, по крайней мере, для меня, независимо от того, насколько хорошо он или плохо разработал свой API - зная, что это большая помощь с точки зрения лучшей производительности обработки ZIP-файлов/потоков.

исх: http://www.splinter.com.au/compressing-using-the-7zip-lzma-algorithm-in/

 Смежные вопросы

  • Нет связанных вопросов^_^