Bonjour à tous, et bienvenue dans cet article visant a présenter deux outils de la suite Ants de Redgate : Ants Memory profiler et Ants Performance profiler.

Pour parler d’outils de débug, la meilleure solution est toujours de se mettre en situation.

John Doe est un artiste contemporain très influent. A tel point qu’il n’a plus le temps de peindre ses toiles. Il a donc chargé un développeur de réaliser un logiciel qui génère des toiles aléatoires pour lui. Le logiciel lui a été livré, malheureusement, John Doe n’est pas satisfait du résultat : le logiciel met énormément de temps a générer ses tableaux, et pire, s’il l’utilise pendant longtemps son ordinateur deviens inutilisable. Vous voila donc appelé à la rescousse, et vous lancez alors vos outils fétiches pour tenter de trouver quel est le problème.

Le logiciel en question peut être trouvé sur Github.

Ants Memory Profiler

Vous commencez donc par étudier le problème de mémoire. En effet, vous avez repéré qu’a chaque génération d’une œuvre, la mémoire utilisée augmente. Nous lançons donc le profiler, et nous pouvons au choix :

  • Nous attacher en lançant l’exécutable
  • nous attacher a un processus déjà lancé.
ANTS memory profiler

On remarque également que la majorité des technologies .net sont couvertes, et qu’un développeur web, SilverLight, Com+ ou autre pourrait également utiliser la suite. Ensuite, nous lançons le profiling. Pour obtenir suffisamment d’information, nous créons une première œuvre, puis prenons un snapshot de l’état du logiciel. Puis, nous relançons une deuxième œuvre, et regardons ce qui a changé.

profiling

A l’œil nu, on remarque déjà l’augmentation mémoire avec le temps. Mais comme nous allons le voir, on peut obtenir beaucoup plus d’information. D’abord, via la liste des classes, que nous allons filtrer sur les classes appartenant a l’espace de nommage du projet. En les ordonnant ensuite par nombre d’instances supplémentaires, on se rend compte que le nombre de MockData augmente beaucoup entre deux œuvres.

Class List

On peut alors ouvrir l’instance categorizer, et voir que les instances supplémentaires sont tenues par une liste présent dans le viewModel principal. Ceci est d’ailleurs confirmé par le “Instance retention graph”.

instance retention graph

On ouvre donc le code pour voir ce qu’il en est, et en effet, la liste “OldMockDatas” est remplie, sans jamais être vidée.

OldFigures.AddRange(Figures);

Si le but était de sauvegarder les œuvres précédentes, quelque soit le but ultérieur, les enregistrer en mémoire n’est pas la solution. On pourrait imaginer les enregistrer dans une base de données, ou tout simplement exporter l’image générée. Dans tous les cas, cette liste doit disparaitre. Une fois celle ci supprimée, on relance le memory profiler, et on se rend alors compte que la mémoire ne dérive plus. Ce 1er problème est donc résolu.

oldfigures

Ants Performance Profiler

Path to .net executable

Nous allons maintenant nous attacher aux problèmes de freeze et de temps d’exécution, en utilisant ce coup ci Ants Performance profiler. On voit en l’ouvrant qu’il y a de nombreuses ressemblances avec le 1er outil. Une fois attaché a notre application, nous lançons la génération d’une œuvre.

Ants performance profiler

On voit que celle ci est extrêmement lente. Lorsque cette génération est terminée, le logiciel nous indique ou se trouvent les chemins critiques en terme de CPU.

CPU

Le souci viens du “PropertYChanged” lancé sur la propriété MockData. Une fois la solution ouverte, on vois que la personne ayant développé ce logiciel n’était pas très au fait du fonctionnement de WCF : a chaque nouvel élément à rajouter dans nos données, il a décidé de créer un nouveau tableau plus grand, et de remplacer l’existant. Pire, pour accélérer le processus, il a parallélisé ce traitement, mais en revenant ensuite dans le thread UI et en le lockant. Pas étonnant donc que les performances ne soient pas au rendez vous. On décide donc de modifier son code, et de remplacer la propriété sous forme de tableau en une ObservableCollection, tout en simplifiant le code d’ajout avec une simple boucle.

PropertYChanged

Une fois nos modifications effectuées, on relance le profiling. Celui ci est nettement plus performant, mais toujours pas idéal. On vois qu’une méthode prend toujours un peu de temps, sans être métier. Ce coup ci via le “current call graph”, nous allons pouvoir savoir exactement ce qui prend du temps dans cette méthode.

profiling

Dès qu’on observe celui ci, il nous saute aux yeux que nous créons des objets à la volée sans raison, il vaut mieux réutiliser toujours les mêmes Brush. On modifie alors cette méthode, et on relance une fois le plus le profiler.

Brush profiling

Ce coup ci, on vois bien que tout le temps de traitement est pris par des opérations “métier”, et que celles ci sont faites d’une manière cohérente. De plus, les temps de latence sont largement acceptables, notre mission est donc réussie.

Ceci conclus cette entrée en matière sur ces deux outils. Vous pouvez retrouver le code de cette démonstration sur GitHub, n’hésitez pas a commenter cet article en cas de questions / remarques.

Ne ratez plus aucunes actualités avec la newsletter mensuelle de SoftFluent