Emit mapper vs valueinjecter или autopper производительность

Я провел некоторое время, сравнивая эти три картографа, и интересно, почему такая большая разница в производительности между emitmapper и любым из valueinjecter или automapper(последние два сопоставимы по производительности). Из бенчмарк-теста в решении 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

Также некоторые тесты из valueinjecter, запущенные с добавленным emitmapper(для 10000 итераций):

    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

Там в первом тесте emit mapper - он создавался каждый раз, во втором - один маппер для всех преобразований.

Принимая это во внимание, получим результат как valueinjecter(также как autopper) медленнее, чем в 100 раз, чем emit mapper. В чем причина такой огромной разницы в производительности? Что касается меня, то сопоставление объекта с объектом не может занимать столько времени по сравнению с рукописным отображением, сколько является узким местом проекта (например, если нам нужно отобразить коллекцию объектов).

В данный момент я думаю об использовании emit mapper, но единственная причина, по которой я не готов принять решение: emit mapper вообще не поддерживается первыми разработчиками, но я не уверен, что это очень важно (очень низкая вероятность требованию некоторого дополнительного функционала).

1 ответ

Причина объясняется в документации EmitMapper:

Он эффективно использует библиотеку Emit для генерации преобразователей во время выполнения напрямую в IL, как будто эти преобразователи написаны вручную. Большинство других картографов используют библиотеку Reflection для отображения (или генерации исходного кода). Также EmitMapper минимизирует операции распаковки и дополнительных вызовов во время сопоставления. Например, он выполняет преобразование типов для типов-значений без распаковки и преобразования вложенных элементов без рекурсии (однопроходный алгоритм), когда это возможно.

Отражение очень медленное по сравнению с рукописным кодом. Вместо этого EmitMapper, по сравнению с рукописным отображением, имеет только накладные расходы при запуске, когда он излучает.

Другие вопросы по тегам