Как стать автором
Обновить

Комментарии 20

спасибо! как раз стоял выбор между подобными библиотеками, теперь очевидно — EmitMapper, да и его fluent интерфейс (после fluentHibernate, Moq и Autofaq) очень и очень приятен.
Спасибо за наводку на EmitMapper и за сравнение производительности. Попробую в своем проекте заменить AutoMapper на EmitMapper. Было бы здорово, если бы еще описали, какие именно особенности реализации дали такую разницу производительности.
Опять какая-то синтетика, да еще и с неправильными замерами. Уж сколько ж раз повторяли, что JIT компилирует каждый метод отдельно, так что для получения хоть сколько-нибудь корректных данных надо каждый метод выполнить отдельно и без замеров производительности.
Время работы тестов по 30-50 секунд. Сами тесты из 5 строк, во всех текст самих тестов практически одинаковый. Так что временем работы JIT'a можно пренебречь
А попробовать?
Проверил. Перед каждым тестом добавил холодный прогон и GC.Collect(), чтобы все находились в равных условиях. Вот результаты:

Auto Mapper (simple): 37652 milliseconds
BLToolkit (simple): 34886 milliseconds
Emit Mapper (simple): 113 milliseconds
Handwritten Mapper (simple): 37 milliseconds
Auto Mapper (Nested): 52456 milliseconds
Emit Mapper (Nested): 91 milliseconds
Handwritten Mapper (Nested): 86 milliseconds
Auto Mapper (Custom): 49348 milliseconds
Emit Mapper (Custom): 188 milliseconds

Вобщем, они практически не отличаются от тех, что в заметке.
Из особенностей, которые так сильно повлияли на производительность самые главные это:
1) В EmitMapper есть возможность заранее сгенерировать мэппер и где-то его сохранить (например, во время старта программы в статическом поле). В AutoMapper и BLToolkit мы вынуждены использовать одну единственную глобальную точку входа типа: «Map.ObjectToObject(foo)». А это затраты на синхронизацию, поиск по словарю и т.д.
2) AutoMapper был изначально спроектирован и написан для Reflection и лишь потом переведен на Emit. Из-за этого там осталось очень много ненужного оверхеда.
3) EmitMapper практически нигде не использует boxing/unboxing в отличии от его конкурентов
В EmitMapper есть возможность заранее сгенерировать мэппер и где-то его сохранить (например, во время старта программы в статическом поле). В AutoMapper и BLToolkit мы вынуждены использовать одну единственную глобальную точку входа типа: «Map.ObjectToObject(foo)». А это затраты на синхронизацию, поиск по словарю и т.д.


Это вранье… «Map.ObjectToObject(foo)» это просто один из вариантов использования. Посмотрите на MappingEngine. Свободно кешиться в синглтоне. Для мебя мы вообще сделали хелперы, и забыли.
Простите, это было про AutoMapper, но быстрее всего если вы глубже копнете, тока окажеться что и в BLTollkit есть что-то подобное.
Я основывался на бенчмарке автора AutoMapper
code.google.com/p/automapperhome/source/browse/trunk/src/Benchmark/FlatteningMapper.cs
Вот кусок кода оттуда:
public void Map()
{
Mapper.Map<ModelObject, ModelDto>(_source);
}

Я полагаю, что автору виднее, как правильно использовать его собственную библиотеку.
Я полагаю, что щас пришлю вам патч, а потом посмотрим.
Сам автор BlToolkit подтвердил, что такого интерфейса нет.
ессно

var configuration = new Configuration(new TypeMapFactory(),
	MapperRegistry.AllMappers.Invoke());
configuration.CreateMap<B2, A2>();
configuration.CreateMap<char, int>();
autoMapper = new MappingEngine(configuration);

я им когда-то сабмитил патч, тобы попроще выглядело, но что есть то есть.

и использование

d = autoMapper.Map(s, d);


Проблема в том что мы не всерано придеться посыпать голову пеплом. При том что про Map.ObjectToObject это действительно вранье. Кеширование конфигруции практически никчему не приводит. Как то так.

Простите. Я просто должен был указать на неточность не более того.
Во-первых, я не понял, в чем заключается «вранье» про «Map.ObjectToObject»?

Во-вторых, я говорил не про кеширование конфигураций, а про кеширование сгенерированного маппера (то есть при маппинге такой маппер не анализирует типы переданных объектов и не генерирует или достает из кеша код. Если бы вы прочитали о чем шла речь, то увидели, что я объяснил просадку производительности. Дак вот, производительность проседает из-за поиска кода по словарю и из-за синхронизации. Об этом я писал выше.

В-третьих у MappingEngine нет метода «Map», который принимает два объекта. Назовите мне номер строки с этим методом здесь:
code.google.com/p/automapperhome/source/browse/trunk/src/AutoMapper/MappingEngine.cs
Метод Map с двумя параметрами нашел, но это не сгенерированный маппер.
public TDestination Map<TSource, TDestination>(ResolutionContext parentContext, TSource source)
{
Type destinationType = typeof(TDestination);
Type sourceType = typeof(TSource);

}

Это не именни никакого отношение к тому, о чем я говорил
А как можно получить тестовый код, так что бы я мог написать «правильный» код для AutoMapper?
Все ссылки есть в статье. Читайте внимательнее.
НЛО прилетело и опубликовало эту надпись здесь
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории