2012-10-24 17 views
21

Ho passato un po 'di tempo a confrontare questi tre mappatori ed è interessante il motivo per cui una così grande differenza di prestazioni tra emitmapper e any valueinjecter o automapper (gli ultimi due sono paragonabili alle prestazioni). Dal test di benchmark in soluzione emitmapper (1000000 iterazioni):Emit mapper vs valueinjecter o prestazioni di automapper

Auto Mapper (simple):  38483 milliseconds 
    Emit Mapper (simple):  118 milliseconds 
    Handwritten Mapper (simple): 37 milliseconds 

    Auto Mapper (Nested):  53800 milliseconds 
    Emit Mapper (Nested):  130 milliseconds 
    Handwritten Mapper (Nested): 128 milliseconds 

    Auto Mapper (Custom):  49587 milliseconds 
    Emit Mapper (Custom):  231 milliseconds 

anche alcuni parametri di riferimento da valueinjecter azionate con emitmapper aggiunto (per 10000 iterazioni):

Convention: 00:00:00.5016074 
    Automapper: 00:00:00.1992945 
    Smart convention: 00:00:00.2132185 
    Emit mapper(each time new mapper): 00:00:00.1168676 
    Emit mapper(one mapper): 00:00:00.0

lì in prova mapper primo Emit - è stato creato ogni volta, in un secondo mappatore per tutte le conversioni.

Tenendo conto di ciò, ha risultato come valueinjecter (anche come automapper) più lento di 100 volte rispetto a emit mapper. Qual è una ragione di così grande differenza di prestazioni? Per quanto mi riguarda, l'oggetto al programma di mappatura degli oggetti non può richiedere molto tempo rispetto al mappatore scritto a mano, in quanto si tratta di un collo di bottiglia del progetto (se è necessario mappare la raccolta di oggetti, ad esempio).

In questo momento sto pensando di usare emit mapper, ma solo una delle ragioni per cui non sono pronto a decidere: emettere il mapper non supportato affatto dai primi sviluppatori, ma non sono sicuro che sia molto importante (possibilità molto bassa di richiedere alcune funzionalità aggiuntive).

+4

È davvero difficile trarre conclusioni dai dati quando non si conosce ciò che è stato testato. Automapper utilizza la riflessione per eseguire la mappatura automatica iniziale e quindi memorizza i risultati nella cache. Se hai rifatto quella parte di ogni iterazione, potrebbe dare risultati negativi. Probabilmente otterrai risposte migliori se mostri come hai eseguito i test. –

+0

Ho usato per la seconda parte come codice base da questa pagina: http: //valueinjecter.codeplex.com/wikipage? Title = SmartConventionInjection & referringTitle = Home per la prima parte Ho usato il progetto di benchmark dal progetto emitmapper dalla homepage di emitmapper (http://emitmapper.codeplex.com) – Igor

+0

Grazie per aver fornito alcuni punti di riferimento, mi ha fatto decidere di non utilizzare Automapper. Ha rallentato tutto drasticamente. – Peter

risposta

11

Il motivo è spiegato int il EmitMapper documentation:

utilizzare efficacemente la libreria Emit per generare mapper in fase di esecuzione diretta in IL, come se questi mapper sono scritti a mano. La maggior parte degli altri mappatori utilizza la libreria Reflection per mappare (o generare codice sorgente). Inoltre, EmitMapper riduce al minimo le operazioni di box-unboxing e le chiamate aggiuntive durante la mappatura. Ad esempio, esegue la conversione dei tipi per i tipi di valore senza boxing-unboxing e converte i membri annidati senza ricorsione (algoritmo one-pass) quando è possibile.

La riflessione è estremamente lenta rispetto al codice scritto a mano. EmitMapper invece, rispetto alla mappatura scritta a mano, ha solo l'overhead di avvio quando emette.