2009-10-05 3 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(); 
    } 
} 
} 

편집 한

을, 나는 다음에 압축 해제 방법을 수정 ,하지만 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

편집 나는 개미 프로파일 러를 사용하여 응용 프로그램을 프로파일 링, 및 압축 해제의 60 년대 동안, CPU는 거의 제로이며, 메모리 사용량이 변경되지 않습니다.

편집 3 실제 둔화

this.Response.GetResponseStream
전체 60 년대의 읽기 동안 것으로 보인다

MemoryStream을에 응답 스트림을로드 소요됩니다. GZipStream을 호출하면 GZipStream에 대한 호출이 빠릅니다.
편집 4

나는 HttpWebRequest.AutomaticDecompression를 사용하여 동일한 성능 문제를 전시 것을 발견, 그래서 나는이 질문을 폐쇄하고있다.

+0

압축 해제가 올바른 문제가 아니기 때문에 투표를 종료하십시오. – Armbrat

+0

메모리 스트림을 추가해도 성능이 향상되지 않는다고 가정하면 실제로 메모리 스트림에 전체 응답을 기록하는 데 걸리는 시간과 별도로 압축하는 데 걸리는 시간을 측정하고 있습니까? CPU가 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

흥미 롭 ... 나는 시스템에서 약 15 초 동안 압축을 풀면 약 70 메가의 압축되지 않은 대형 XML 파일을 가지고있다. 정말 코드와 관련이 있는지 궁금해지기 시작했습니다. 해당 시스템에서 바이러스 백신을 살펴볼 수 있습니까? 아마 그걸 끊었을거야. 우리는 IBM에서 Etrust를 사용하는 데 많은 시간을 할애하여 파일을 끊는 데 많은 어려움을 겪었습니다. 원한다면 코드 샘플을 제공 할 수 있지만 다시 코드 관련이 없다고 생각합니다. –

+0

나는 병 목이 될 수있는 다른 것을 생각하려고합니다. 해당 시스템에서 메모리 테스터를 실행할 수 있습니다. RAM에 결함이있을 수 있습니까? 나는 단지 뇌를 밀어 내고있다. 이상하게 보입니다. –

1

DotNetZip는 드롭 System.IO.Compression.GZipStream 리 교체 용으로 사용할 수있는 GZipStream 클래스를 갖는다.

DotNetZip은 무료입니다.

NB : GZipStream 만 수행하는 경우 Ionic.Zip.dll이 아니라 Ionic.Zlib.dll이 필요합니다.

+0

DotNetZip/Zlib 라이브러리를 사용했지만 동일한 성능 문제가 발생했습니다. – Armbrat

+0

그렇다면 DeflateStream이 아닌 것 같습니다. 어쩌면 당신은 기억 문제가있을 것입니다. 어쩌면 더 많은 반복을 테스트해야 할 것입니다. 단일 반복, 단일 시험을 기반으로 성능에 대한 결론을 내리기가 어렵습니다. – Cheeso

+0

"더 많은 반복 테스트"에서 의미하는 바를 따르지 않습니까? 이것은 동일한 서버에 대한 많은 요청 중 하나입니다. 대부분의 요청은 ~ 10k 데이터 만 반환합니다. 이것은 유일한 "대규모"요청이며 약 150k입니다. – Armbrat

0

필자는 3 센트를 주제에 드롭하여 C# 사용자에게 7Zip이 평이한 C#으로 API를 드러내는 것처럼 보일 것입니다.저는 여러분 모두가 7Zip 툴을 아주 잘 알고 있다고 생각합니다. 적어도 API가 얼마나 잘 설계되었는지에 상관없이, ZIP 파일/스트림 처리 성능면에서 큰 도움이된다는 것을 알고 있습니다.

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

관련 문제