Optimiser du code utilisant la reflexion avec FastMember

Robin

L’application sur laquelle je travaille actuellement calcule des positions à partir d’objets COM modélisant les deals passés dans le système. La volumétrie est importante et il est nécessaire de wrapper ces composants COM dans des objets .NET utilisables par mon application. Ces objets COM sont complexes et de plusieurs types (un par type de deal).
Cependant, l’application est basée sur un modèle de deal C# plat, prenant en charge tous les types de deal et gardant une référence vers le deal COM associé. Chaque appel à une propriété de cet objet C# entraîne une reflexion sur le deal COM sous-jacent afin d’en déterminer la valeur.

Les propriétés de cet objet ressemblaient à peu près à ça:

J’ai récemment effectué une refonte de ce processus, en créeant une Factory instantiant dès le départ toutes les propriétés du deal .NET à partir du deal COM, sans garder de référence entre les deux.

Ce refactoring a eu un impact très important sur l’utilisation mémoire de l’application (un facteur 2-3), mais les performances étaient assez catastrophiques. Etant donné que les deals COM pouvaient être de types différents et inconnus au runtime, il était nécessaire d’utiliser la reflexion pour déterminer la valeur des propriétés (sachant qu’il fallait extraire 40 propriétés par deal COM).

Alors que je reflechissais aux pistes d’optimisation, j’ai découvert FastMember, une librairie développée par l’un des membres les plus actifs de la communauté StackOverflow : Marc Gravell. Il annonçait des métriques démentielles sur son blog relatives à l’accès aux valeurs de propriétés, à savoir:

Static C#: 14ms
Dynamic C#: 268ms
PropertyInfo: 8879ms
PropertyDescriptor: 12847ms
FastMember.TypeAccessor.Create: 73ms
FastMember.ObjectAccessor.Create: 92ms

La librairie est très simple à utiliser:

Effectuer un wrapping initial sur l’objet sur lequel va s’effectuer la reflection :

Ce wrapping initial est un peu coûteux, mais les accès ultérieurs aux propriétés de l’objet seront très rapides, et on s’affranchit complètement de la syntaxe lourde de la réflexion :

Dans mon cas, j’ai implémenté une méthode simple dans ma Factory, permettant de récupérer la propriété du deal COM ou de spécifier une valeur par défaut, au cas où le deal COM n’a pas la propriété interrogée :

L’utilisation de cette librairie a viabilisé mon projet de refactoring, et on est proche des perfs que l’on attendrait d’un code C# statique !

facebooktwittergoogle_plusmail

Laisser un commentaire