Automapper and JIT compilation
Recently I investigated one bottleneck in an application and it turned out reason was quite simple: unexpected JIT compilation because of improper AutoMapper usage
Simplified mapper definitions looked like this:
class SrcClass{
public String StrValue { get; set; }
}
class DestClass{
public Double Value { get; set; }
}
class DemoMapper : IMapper
{
public DemoMapper()
{
Mapper.CreateMap<SrcClass, DestClass>()
.ForMember(dst => dst.Value, opt => opt.MapFrom(src => src.StrValue));
}
public TDestination Map<TSource, TDestination>(TSource sourceObject)
{
return Mapper.Map<TSource, TDestination>(sourceObject);
}
}
Typically, mapper was retrieved using IoC container:
var srcObject = new SrcClass(){StrValue = "123.456"};
var mapper = IocFactory.Get<IMapper>();
var dstObject = mapper.Map<SrcClass,DestClass>(srcObject);
If we run code above 10000 times and then look to PerfView measurements results, we can see that more than 50% CPU time was spent on expression compilation, causing lots of JIT compilation
What happened here is that within every cycle we’ve initialized mapping configuration and every time Automapper internally re-created mapping method and compiled it. Real life project had hundreds of auto-mapped properties, causing noticeable performance decrease even on powerful servers. Solution is to do heavy initialization once: either do initialization in static constructor or alter IoC configuration to implement this class as a singleton.
...
static DemoMapper()
{
Mapper.CreateMap<SrcClass, DestClass>()
.ForMember(dst => dst.Value, opt => opt.MapFrom(src => src.StrValue));
}
...