[PDC 2009] WPF Performance Tuning and Analysis
Voilà une session que j’ai nommé “Killer Session” ! (en fin de journée je vous explique pas !)
Session animée par deux (jeunes) membres de l’équipe WPF Performance (Blogs http://blogs.msdn.com/jgoldb/ et http://blogs.msdn.com/ricom)
Autant le dire de suite, ces deux jeunes envoient du bois !
Je ne vais pas rentrer dans les détails, la session est très technique. Quelques slides pour résumer la philosophie du truc :
Oui les mesures, et surtout l’expérience !
je ne résiste pas à la tentation de vous montrer un des exemples découvert pendant la session:
Il s’agit d’éviter de charger des modules inutilement dans votre code.
Supposons que j’ai dans un “IF” un appel à un objet externe, faisant parti d’une dll supplémentaire :
1: // Some code
2: // /...
3:
4: if (!expected)
5: {
6: using (COMClassLogger log = new COMClassLogger())
7: {
8: log.WriteLog("Error");
9: }
10: }
11:
12: // Some code
13: // /...
Votre module est loadé lors du chargement de l’assembly principal, alors que celle ci peut ne pas être utilisé (Peut être parce qu’on passe pas dans le IF
)
Oui monsieur, l’évaluation du IF est fait au runtime, pas à la compil !!!
Le truc pour éviter ça c’est d’exporter votre appel dans une méthode, “like this” :
Si lors du chargement, votre module supplémentaire ne fait pas parti du corps de la méthode de chargement, il ne sera pas chargé. On fait donc un truc du genre :
1: // Some code
2: // /...
3:
4: if (!expected)
5: {
6: WriteLogEntry();
7: }
8:
9: // Some code
10: // /...
11: }
12:
13: private void WriteLogEntry()
14: {
15: using (COMClassLogger log = new COMClassLogger())
16: {
17: log.WriteLog("Error");
18: }
19: }
Le problème c’est le JIT compiler va optimiser ce code est “coupé-coller” le corps de la méthode au niveau de l’appelant. Donc un coup d’épée dans l’eau !
Bref, il nous faut donc indiquer à .NET de ne PAS faire faire ce qu’on appelle du “Inlining”, en marquant notre méthode avec un attribut MethodImpl, “like that” :
1: [MethodImpl(MethodImplOptions.NoInlining)]
2: private void WriteLogEntry()
3: {
4: using (COMClassLogger log = new COMClassLogger())
5: {
6: log.WriteLog("Error");
7: }
8: }
Et voilà un module non chargé, qui pourrait bien faire ramer (potentiellement) notre application au démarrage !
C’était je pense un des exemples les plus simple de la session
Nos deux compères ont beaucoup utiliser les outils de traces à disposition; voici un bon slide qui résume ceux qu’ils ont utilisé :
Voilà, bonne optimisation à tous