XXP

mai 2016

lun. mar. mer. jeu. ven. sam. dim.
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          

« Emit Mapper copie plus vite qu'Automapper | Accueil | Emit Mapper copie plus vite qu'Automapper »

07 janvier 2010

Emit Mapper copie plus vite qu'Automapper

Codeplex-logo_3  On a souvent besoin de copier les propriétés d'un objet en mémoire vers un autre, y compris entre des objets de types différents. (Si cette première phrase vous semble être en Na'vi, la suite confortera cette impression). En mode "quick win", un petit bout de code qui recopie une par une les propriétés fonctionne très bien. 

Oui, ça marche, mais, las, le résultat est fragile : vous le savez très bien, un jour quelqu'un, peut-être vous un vendredi soir à 21h (ah non pas vous), va ajouter une propriété sur ces objets et oublier d'ajouter aussi une ligne dans cette méthode de recopie. S'en suivra peu à peu la faillite du système : une corruption de la base de données, des transactions financières aberrantes, votre nom dans les journaux et un milliard d'Euros à rembourser de votre poche. La loi de Murphy n'aide pas, mais si vous aidez la loi de Murphy... Et encore je ne parle même pas d'une mise en production le 21 décembre 2012... 

Bref dans le cas présent le quick win est un big loss pour qui intègre le futur dans sa vision du monde.

Vous allez me dire que vous travaillez en mode Agile (pas Agile à la sauce Coué, mais le vrai mode Agile, celui qui se donne des moyens) et que vos tests unitaires vous protègent. C'est tant mieux, mais si la vérification de la copie des objets est elle aussi manuelle, la nouvelle propriété ne sera probablement pas testée -- on a oublié de modifier la méthode, pourquoi penserait-on au test unitaire associé ? Et si jamais votre test est solide parce que vous avez eu la bonne idée d'utiliser les APIs de reflection pour l'implémenter, il est probable que vous allez employer la même ruse pour implémenter la méthode de recopie...

Bref, simplifiez-vous la vie, réinventez d'abord la roue parce que c'est amusant et formateur, puis choisissez un outil spécialisé qui marche mieux que le vôtre (désolé). 

Emit Mapper est un de ces outils, et les premiers tests le présentent comme 400 fois plus rapide (mais voir § ci-dessous) que son concurrent Automapper parce qu'il s'appuie sur la librairie Emit (code de recopie généré une seule fois) plutôt que sur les API de Reflection (chaque copie va déclencher les mêmes appels aux méthodes de reflection, quoiqu'il y a des astuces à connaitre).

Attention : comme l'a fait remarquer Romain dans les commentaires, Automapper utilise aussi Emit (depuis aout 2009). Peut-être que le benchmark date un peu, peut-être que l'auteur est optimiste (mais cf. ci-dessous). Le chiffre 400 est donc à prendre avec le doute et le recul d'un scientifique qui lit une boîte de Chocapic. Si l'un de vous a le courage de comparer...

Deuxième mise à jour : Vladimir Romanko, l'auteur d'Emit Mapper, vient d'expliquer dans les commentaires les raisons de cette différence impressionnante de performance. Il précise aussi que les benchmarks ont été écrits de façon impartiale, et que les mesures sont faciles à reproduire puisque les benchmarks font partie des sources.

Emit mapper fonctionne sous .Net, Mono et Silverlight. Il vient de sortir en version 1.0 sur Codeplex

TrackBack

URL TrackBack de cette note:
http://www.typepad.com/services/trackback/6a00d8341c871f53ef012876b12dfd970c

Listed below are links to weblogs that reference Emit Mapper copie plus vite qu'Automapper:

Commentaires

C'est rigolo, j'ai réalisé un "Emit mapper" il y a plus d'un an pour mon client. Je suis curieux de voir comment il se situe au niveau des performances (à l'époque je n'avais rien trouvé de mieux). D'un autre côté la comparaison dont tu parles m'étonne un peu : il me semblait que depuis un moment, AutoMapper utilisait également SRE (ou des expressions compilées).

C'est vrai que les chiffres sont étonnants. Il n'est pas impossible que le benchmark publié par Vladimir Romanko ait une forte composante marketing. D'où la tournure de précaution "les premiers tests le présentent..."...

Et tu as raison, Automapper utilise Emit depuis le mois d'aout (cf. par exemple http://code.google.com/p/automapperhome/source/browse/trunk/src/AutoMapper/Internal/DelegateFactory.cs).

Bien vu et merci -- je modifie le post pour l'indiquer.

c'est drole je viens juste de mettre en place AutoMapper sur un de nos projets.
La perf est importante effectivement, mes les fonctionnaltés aussi.
J'ai du mal avec la documentation de Emit Mapper, je trouve le site de AutoMapper bien plus clair.
Mais bon je suis pas fufute moi.
Bonne année !

Sorry, I don't speek french. Folks, you can themself run benchmarks which are part of the EmitMapper source code pack and you will be able to inspect if benchmark tests were written fairly (actually they are :) as well as you will be able to see huge perfomance difference between AutoMapper and EmitMapper. The reason for that perfomance gap is that AutoMapper was originally developed on the Reflection library and afterwards migrated to Emit. In contrary the EmitMapper was originally designed for Emit library and it has lot of optimization trics: for example it performs type conversion for value-types without boxing-unboxing; it converts nested members without recursion (one-pass algorithm) and so on.

If you have any troubles or questions about EmitMapper please post them there: http://emitmapper.codeplex.com/Thread/List.aspx

Thank you for your comment Vladimir. Your explanation about this very impressive performance gap makes sense, and it's good to know that the benchmark tests are fair.

Nice challenge, bravo -- and keep up the good work !

Salut Denis.
J'ai découvert il y a quelques mois AutoMapper, très satisfait du projet, notamment API et doc. Je ne connais pas EmitMapper. Il semble donc très performant, mais , d'après la doc, l'API me semble plus pauvre.
Par exemple, moi qui veut des objets convertis immutables, j'utilise le constructeur adéquat via AutoMapper, mais je vois pas comment faire avec EmitMapper.

Merci Denis!

Juflo, jetez un coup d'oeil là: http://emitmapper.codeplex.com/wikipage?title=Customization%20using%20default%20configurator&ANCHOR#Custom_constructors
... si j'ai bien compris votre question

L'utilisation des commentaires est désactivée pour cette note.