Introduction
Cet article traite des résultats des différentes méthodes pour lire une image provenant d’un site Http.
Les différentes implémentations ont été décrites dans l’article
Image depuis http avec C# Xaml – comparatifs et performances.
Mesures
L’image étalon fait 19ko et mesure 400×240 pixels. Elle est présente notamment sur les serveurs de Bing à l’adresse suivante :
http://www.bing.com/az/hprichbg/rb/ChristmasMarketNurnberg_FR-FR11351563819_1280x768.JPG
Le premier test va charger 10 fois la même image suivante :
Afin d’éviter les mises en cache http d’échanges, l’url demandée est accompagnée de paramètres fictifs dans la requête.
Exemple : http://192.168.0.47/ChristmasMarketNurnberg_FR-FR11351563819_400x240.jpg?test={0} où {0} sera remplacé lors des tests par des données uniques avec l’instruction
String.Format(url, DateTime.Now.Ticks)
Une méthode générique de benchmark a été réalisée. A titre indicatif, voici la méthode principale.
public static async Task BenchmarkTest(this IBenchmarkResult result, Func<string, Task<object>> test, string url, string title, string comment) { await semaphore.WaitAsync(); try { string resourceName = String.Empty; _buildLog.AppendLine("-----------------------"); _buildLog.AppendLine(String.Format("Test {0} (x{1})", title, _nbBench)); _buildLog.AppendLine(String.Format("-- {0} ", comment)); result.BenchmarkLog= _buildLog.ToString(); _startTime = DateTime.Now; _buildLog.AppendLine(String.Format("Start {0:HH:mm:ss}", _startTime)); int nb = 0; int index = 0; while (nb > 0 || index <= _nbBench) { index++; if (index <= _nbBench) { nb++; { System.Diagnostics.Debug.WriteLine("Add test {0}, index {1}", nb, index); result.Image = await test(String.Format(url, DateTime.Now.Ticks)); nb--; System.Diagnostics.Debug.WriteLine("remove test {0}", nb); } } } _buildLog.AppendLine(String.Format("Result {0} = {1:0.000} s", title, (DateTime.Now - _startTime).TotalSeconds)); result.BenchmarkLog = _buildLog.ToString(); } finally { semaphore.Release(); } }
- Le sémaphore sert à éviter les conflits
- La méthode à tester est passée dans la Func Test
- La boucle lance les tests à la suite (10x pour ces tests)
Pour rappel, les méthodes testées sont les suivantes :
- Http client et DataWriter : implementation classique avec le DataWriter
- Http Client et AsRandomAccessStream : utilisation du AsRandomAccessStream (W8.1)
- HttpClient et AsRandomAccessStream avec ConfigureAwait : optimisation avec ConfigureAwait(false)
- HttpClient et MemoryStream dans une autre Task. Le memoryStream est traité à part dans une tâche asynchrone
- HttpRequest et MemoryStream dans une autre Task Le HttpRequest est utilisé à la place du HttpClient
- Actions à la place du Async / Await : Utilisation des Actions à la place du async/await
- HttpWebRequest et AsRandomAccessStream :
- HttpWebRequest et AsRandomAccessStream avec Action : comme la 6 mais AsRandomAccessStream remplace la Task du MemoryStream
- HttpWebRequest, AsRandom Access Stream sans ConfigureAwait : Idem que la 2 mais avec HttpWebRequest
Test en local
Le test est réalisé sur un réseau local, via Wifi sur un Lumia 930. Les tests ont été mélangés (pour ne pas toujours commencé par le premier)
Le serveur est situé sur le réseau local.
Le tableau représente les valeurs en ms pour chaque série de tests.
Les moyennes sont sur la première ligne.
On peut déjà voir de gros écarts entre la première méthode traditionnelle et la 8, nous avons presque des temps qui sont divisés par 2.
On observe également que
- Le HttpClient est bien plus lent que le HttpRequest (ce n’est pas une surprise)
- Les méthodes utilisant des actions sont les plus rapides (pourquoi reste le grand mystère inexpliqué)
Test grandeur nature
Le test a ensuite été réalisé sur des connections 3G, 4G, Wifi avec un serveur distant.
Le serveur utilisé est le serveur de Bing. Les temps de connexions sont bien sûr plus variables et voici les résultats sur une connexion H+ réseau orange avec le 930.
Les moyennes sont toujours sur la première ligne.
Peu de différences avec les tests sur réseau local.
Les benchmarks 3, 6, 8 et 9 sont les meilleurs et seront conservés pour les autres tests
Le test suivant est réalisé sur un 920, toujours sur un réseau H+.
Sur un Lumia 920, les méthodes 6 et 8 sortent du lot avec un gain d’une dizaine de pourcent.
J’ai pu faire des tests à plusieurs reprises sur des réseaux allant de la 4g au Edge et ce sont toujours ces 2 implémentations qui sortent du lot.
Conclusion
Dans mes Apps, je vais utiliser l’implémentation 8 qui reste simple (comparée à la solution 6), compréhensible et une des plus performantes.
Il serait intéressant de voir également si des téléphones avec un processeur un peu moins performant tel que le Lumia 520 enregistrent les mêmes écarts.
Le code source sera publié très prochainement.