22

私はこの 3 つのマッパーを比較するのに時間を費やしましたが、emitmapper と valueinjecter または automapper のいずれか (最後の 2 つはパフォーマンスで比較可能) との間でなぜこれほど大きなパフォーマンスの違いがあるのか​​ということは興味深いことです。emitmapper ソリューションのベンチマーク テストから (1000000 回の反復):

    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

また、追加されたemitmapper(10000回の反復)で実行されたvalueinjecterからのいくつかのベンチマーク:

    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.0012337

最初にエミットマッパーテストがあり、毎回作成され、2番目にすべての変換に対して1つのマッパーが作成されました。

これを考慮して、値インジェクター (オートマッパーとしても) としての結果を、エミット マッパーよりも 100 倍遅くします。これほど大きなパフォーマンスの違いの理由は何ですか? 私にとって、オブジェクトからオブジェクトへのマッパーは、プロジェクトのボトルネックになるため(たとえば、オブジェクトのコレクションをマップする必要がある場合)、手書きのマッパーに比べてそれほど時間がかかりませんでした。

現時点では、エミットマッパーの使用を考えていますが、決定する準備ができていない理由は 1 つだけです: エミットマッパーは最初の開発者によってまったくサポートされていませんが、これが非常に重要かどうかはわかりません (可能性は非常に低いです)。いくつかの追加機能の要件に)。

4

1 に答える 1

12

その理由は、EmitMapper のドキュメントで説明されています。

Emit ライブラリを効果的に使用して、マッパーが手動で記述されているかのように、実行時に IL で直接マッパーを生成します。他のほとんどのマッパーは、マッピング (またはソース コード生成) に Reflection ライブラリを使用します。また、EmitMapper は、マッピング中のボックス化とボックス化解除の操作と追加の呼び出しを最小限に抑えます。たとえば、ボックス化とボックス化解除を行わずに値型の型変換を実行し、可能な場合は再帰 (ワンパス アルゴリズム) を使用せずにネストされたメンバーを変換します。

リフレクションは手書きのコードに比べて非常に遅いです。代わりに、EmitMapper は、手書きのマッピングと比較して、発行時の起動オーバーヘッドのみを持ちます。

于 2013-05-08T10:54:15.447 に答える