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
The mappers I’ll be comparing are:
AgileMapper
My mapper project, now on version 0.9. AgileMapper focuses on ease of use, flexibility and transparency.
AutoMapper
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
ExpressMapper is a ‘lightweight’ mapper, first written as a faster alternative to the AutoMapper 4.x.x series.
Mapster
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
ValueInjecter is written for flexibility, and supports unflattening as well as flattening.
The Tests
The performance test project is a console project based on the AutoMapper benchmark which performs each of the following, for each mapper, 1 million times:
-
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
Foo
,List<Foo>
andFoo[]
properties, andIEnumerable<int>
andint[]
properties -
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
The Nuances
I had a pull request to add the
AllowPartiallyTrustedCallers
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 AllowPartiallyTrustedCallers
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
around slapping AllowPartiallyTrustedCallers
on everything then kick back to think what you’ll
do with all the execution time you’ve saved :)
Results Time!
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 AllowPartiallyTrustedCallers
applied.
Constructor | Complex | Flattening | Unflattening | Deep | |
---|---|---|---|---|---|
Manual | 0.00880 | 1.56607 | 0.05303 | 0.05021 | 0.47373 |
AgileMapper 0.9 | 0.15377 | 3.49969 | 0.33809 | 0.50427 | 1.09299 |
AgileMapper 0.9 w/ APTC | 0.13513 | 2.00515 | 0.21154 | 0.38073 | 0.57013 |
AutoMapper 5.2 | 0.16253 | 7.60686 | 0.38347 | - | 0.97259 |
AutoMapper 5.2 w/ APTC | 0.15512 | 6.22497 | 0.23118 | - | 0.57299 |
AutoMapper 4.2.1 | 1.16314 | 118.58244 | 3.47239 | - | 23.18986 |
ExpressMapper 1.8.3 | 0.21227 | 14.15144 | 0.51291 | - | 6.25267 |
Mapster 2.6.1 | 0.03146 | 3.23346 | 0.20822 | - | 0.73005 |
ValueInjecter 3.1.1.3 | 0.44900 | 98.57722 | 12.67822 | 13.59581 | 27.74575 |
Points to Note
-
Mapster is still the fastest at churning out simple mappings - look at that constructor test time!
-
AgileMapper with
AllowPartiallyTrustedCallers
applied 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 :)
Comments
2 comments