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 :

image

Oui les mesures, et surtout l’expérience !

image

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é :

image

 

Voilà, bonne optimisation à tous :)