Development of enterprise software often require creation of APIs for each application components. On implementation phase this involves mapping between API models on different layers of components (e.g. mapping persistence model to domain model to DTO). Such mapping often prone to boiler plate code, consuming development efforts and time.
There are multiple libraries which aim to solve this problem:
- some of them automate mapping only partially. For example Spring Framework’s BeanUtils capabilities are limited with only primitive types and fields of only one class. It can not convert object hierarchy to another object hierarchy.
- others provide full automation of mapping process (e.g. Dozer), they allow to handle complicated cases, like mapping lists of object to maps of primitives. Automation usually comes at a price of performance degradation. The more complicated model is converted the more time it will take to map objects. This is usually caused by the fact that mapping libraries often use reflection and dynamic type resolution to support generic logic of conversion.
There is new player in the market of object mapping, called Orika. This library provide solution in automating mapping using code generation. Code is generated in the manner like it would be written by developers to map one bean to another. With Orika it takes just few minutes to add a library to the project and write couple lines of code to enable mapping between types. Everything else would be done by Orika it self. Though developers of Orika have prepare exhaustive functional documentation they did not provide any prove of performance efficiency. Lets compare all alternatives enumerated above:
- Dozer — each bean is created using reflection, mapping is customized using XML and Java code.
- Orika — beans are created and initialized using code generated by library, mapping can be customized using Java code and own expression language.
- Manual conversion — each bean is created and initialized with code written manually. All conversion is performed in Java code.
Data model that has been used for test include combinations which usually appear in Java Beans, such as:
- object types
Source code of tests is available at GitHub.
Tests has been performed on:
- OS: Linux 2.6.32 x86_64
- CPU: 2.0GHz 4MB cache × 8 cores
- RAM: 16GB
-Xmx1g -Xms1g -XX:MaxPermSize=128m -XX:NewSize=512m -XX:MaxNewSize=512m -XX:SurvivorRatio=6 -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSIncrementalMode
- Number of iterations 1 000 000
Major GC was not happened during test.
Following test results were received:
|Min, nano seconds||290 000||21 000||3 000|
|Mid, nano seconds||318 000||32 000||4 000|
|90%, nano seconds||390 000||41 000||5 000|
|95%, nano seconds||436 000||45 000||5 000|
|99%, nano seconds||534 000||54 000||6 000|
|99.9%, nano seconds||730 000||114 000||33 000|
|99.99%, nano seconds||1 607 000||374 000||65 000|
|99.999%, nano seconds||7 574 000||1 032 000||580 000|
|99.9999%, nano seconds||21 171 000||7 952 000||1 387 000|
|Max, nano seconds||21 171 000||222 581 000||9 810 000|
Orika has maximum latency which differs from general distribution. This latency appears only once at first conversion, when Orika actually perform code generation for mappers.
Orika’s latency has considerable deviation form Manual mapping, this caused by unnecessary object recreations performed by Orika. For example, when string is shifted from on variable to another, new string is created using concatenation with empty string.
In general test proved that Orika is is almost as efficient as manually written code and much more performant than Dozer.