Ok, first of all, I’m definitely going to write about something other than mapper performance soon. This is my third blog on the subject and I want to talk a bit about some unique AgileMapper features! But we’ve got new versions of AgileMapper, AutoMapper and Mapster - the latter including a fix for the bug I found writing my last blog on this subject - and some nuances to talk about.
As this is my third update on this subject - and as it’s Christmas time - here’s the mappers and tests we’re talking about, so you don’t have to visit the previous blogs. You’re welcome! :)
The mappers I’ll be comparing are:
My mapper project, now on version 0.9. AgileMapper focuses on ease of use, flexibility and transparency.
You all already know about AutoMapper - it’s AutoMapper! I’m now testing version 5.2.0, as well as version 4.2.1, as requested by a reader.
ExpressMapper is a ‘lightweight’ mapper, first written as a faster alternative to the AutoMapper 4.x.x series.
Mapster is another ‘lightweight’ mapper, written to be “kind of like AutoMapper, just simpler and way, way faster” (quoted from their NuGet page). Now on version 2.6.1, and the author has optimised its use in my tests.
ValueInjecter is written for flexibility, and supports unflattening as well as flattening.
Constructor mapping - creating a POCO with a single constructor parameter from a POCO with a matching property
Complex mapping - deep cloning a Foo POCO with various kinds of value type properties, multiply-recursive
Flattening - mapping from a POCO with nested POCO properties to a POCO with all value type (and string) properties
Unflattening - mapping from a POCO with all value type (and string) properties to an object with nested POCO properties - only AgileMapper and ValueInjecter support this at the time of writing
Deep mapping - mapping a POCO with nested POCO and POCO collection properties onto a differently-typed POCO with corresponding properties
I had a pull request to add the
attribute to the test project. As explained in this StackOverflow question,
Funcs compiled from Expression trees are hosted in dynamically-created, partially-trusted
assemblies; subsequent executions of these Funcs incur a security overhead. Applying
AllowPartiallyTrustedCallers to the calling assembly causes part of the security checks to
be skipped, which speeds things up.
As you’d expect, that’s not the whole story, though - assemblies marked with
can only call assemblies with compatible security settings. Applying it to the test project means
it can’t call ExpressMapper, Mapster, ValueInjecter or AutoMapper 4.2.1. So you can’t just go
AllowPartiallyTrustedCallers on everything then kick back to think what you’ll
do with all the execution time you’ve saved :)
Here’s the updated results - as mentioned, the numbers are the total seconds required to perform 1
million iterations of each test. ‘w/ APTC’ is the time with
|AgileMapper 0.9 w/ APTC||0.13513||2.00515||0.21154||0.38073||0.57013|
|AutoMapper 5.2 w/ APTC||0.15512||6.22497||0.23118||-||0.57299|
Points to Note
Mapster is still the fastest at churning out simple mappings - look at that constructor test time!
AllowPartiallyTrustedCallersapplied is the fastest at performing non-simple mappings - quite pleased with that! :)
As mentioned previously, the performance improvements in AutoMapper 5 were huge
Ok, that’s it - no more Mapper performance talk… for a while. Stay tuned for some blogs on some unique things AgileMapper can do for you :)