J'ai une application .NET 2.0 WinForms qui se connecte à un serveur WAS backend. J'utilise GZipStream pour décoder les données provenant d'un appel HttpWebRequest fait au serveur. Les données renvoyées sont CSV compressé, compressé par Apache. La pile entière du serveur est Hibernate -> EJB -> Spring -> Apache.Les performances de la décompression GZipStream sont médiocres
Pour les petites réponses, les performances sont bonnes (< 50ms). Quand je reçois une réponse> 150 Ko, il faut plus de 60 secondes pour décompresser. La majorité du temps semble être passé dans le constructeur GZipStream.
Ce code montre l'endroit où je reçois le flux de réponse de l'appel 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();
}
}
}
Modifier 1
Basé sur le commentaire de Lucero, j'ai modifié la méthode Décompresser à ce qui suit , mais je ne vois aucun avantage de performance de charger le ResponseStream dans un MemoryStream avant d'instancier le 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();
}
}
}
}
Basé sur le code ci-dessus, quelqu'un peut-il voir des problèmes? Cela me semble assez basique, mais ça me rend fou.
Edit 2
I profilées l'application en utilisant ANTS Profiler, et dans les années 60 de décompression, l'unité centrale est proche de zéro et l'utilisation de la mémoire ne change pas.
Edit 3
Le ralentissement actuel semble être au cours de la lecture de
this.Response.GetResponseStreamLes années 60 entièrement passé le chargement du flux de réponse dans le MemoryStream. Une fois qu'il est là, l'appel à GZipStream est rapide.
Modifier 4
Je trouve que l'utilisation HttpWebRequest.AutomaticDecompression présente le même problème de performance, donc je ferme cette question.
Voter pour fermer parce que la décompression est pas la question correcte. – Armbrat
Lorsque vous dites que l'ajout du flux de mémoire n'a pas amélioré les performances, mesurez-vous en fait le temps nécessaire pour compresser séparément le temps qu'il faut pour écrire toutes les réponses dans le flux de mémoire? Mon soupçon est, étant donné que le processeur est proche de zéro, que le goulot d'étranglement n'est pas le zipping, mais à quelle vitesse vous pouvez télécharger la réponse. –
Avez-vous résolu ce problème? – rolls