AutoMapper is a library, available in .NET, that has a goal to map an object to another. It’s very used because is very simple and easy to do these mappings.
So in this article, we’ll show you how to do these mappings using other ways and build a benchmark to compare which is best.
The use cases
We’ll build three global use cases:
- With a simple class: its properties are all primitive data types and have the same name as the model class.
- With a complex class: it has properties that are primitive data types, it is also composed of a class and a list of a different class.
- With a complex class which its properties’ name is different from the model class: it is the same as the previous use case but with the different properties name from the model class.
In all these use cases we’ll build some ways of mapping:
- Using the AutoMapper library
- Using an ExtensionMethod that receives a model class and pass it to the entity class using the constructor.
- Using a Method inside the Entity Class that receives a model class and pass it to the entity class attributing the values to its properties.
All use cases are going to be tested with 1, 10, 100, 1.000, 10.000, 100.000, and 1.000.000 records. And for the tests that use more than one record, we’ll iterate the list using Lambda Expression, For, Foreach, Parallel.For and Parallel.Foreach techniques. However, for this benchmark, we will just consider the simple operations, to iterate the lists, using Lambda Expression.
All the tests were executed on Dell’s laptop which has the following configuration: Intel Core i7–8665U, 16GB of RAM memory, and 64-bit of Operation System. Finally, always run your code in release mode for performance benchmark. Running your code in Debug mode can be 10x slower.
Somethings about the code and structure
In the structure, we have only a project which is a Console Application. Into this project, we have three folders that represent the Use Cases and we have another folder which is the common codes.
- The Use Cases folders:
- Entities folder: to represent the classes that we want in the end.
- Models folder: to represent the classes to receive the data and that will be converted to an entity.
- UseCases folder: contains the AutoMapper, CreateMethod, and ExtensionMethod operations.
- Mock class: a static class that contains the mock generator.
- Run class: the class that calls all the Use Case operations referring.
- The Shared folder:
- GenerateList class: contains the methods to generate lists with different operations, like For, Foreach, and Parallel.
- LogRecord class: to store the benchmarks information.
- Execution class: it’s a class that contains a method that receives a delegate that executes something during 1 million interactions.
- RunCases class: it’s a class that contains a method that receives a delegate, a use case identifier, and the number of interactions, to execute the use case. And this class will generate the benchmark information too.
Analyzing the Case 01
With classes that have the same properties name.
In most cases, the Create Method had better performance than others and less spent Memory RAM. But, when we iterate a list with one million interactions, the Create Method lost to the AutoMapper, so much in performance how much in Memory RAM spent.
Analyzing the Case 02
With classes that have the same properties name, and has other properties that are class and compose it.
In most cases, the Create Method, too, had better performance than others and less spent Memory RAM, so, according to the results, this method was better than others.
Analyzing the Case 03
With classes that have different properties name, and has other properties that are class and compose it.
Again the Create Method shows that it’s better than others, but the difference with AutoMapper is not too much.
The best results
For performance and RAM memory spent, the Create Method it’s better than others, in major cases.
For all scenarios have been analyse which is better. If you want ever preserve the performance and/or the RAM memory spent, you will must use the Create Method, but with you want to preserve the best practice, clean code, non-complex code, and organized code, you will must use the AutoMapper.
For the small iterates, maybe it's better you use the ExtensionMethods or CreateMethod than AutoMapper, but pay attention to the number of properties that contain in your class and if they have the same names. If your class has many properties, the methods that will receive these properties will receive many parameters and, in this case, you increase the complexity and it’s not a good pattern to follow.
AutoMapper has some strategies to increase your performance like it’s map the properties once for the next it’s use something like a cache, and for the properties that don’t have the same name and it’s not informing it, the mapper just ignore it.
So, I believe that, for the best practices, you have to consider the AutoMapper use, because this is simple to use, it’s not verbose or complex and the performance and RAM memory spent difference is minimum, compared for others.
The code that was built to do it is on GitHub.