Back to Mapster

Benchmark results

docs/articles/benchmarks.md

10.0.1010.1 KB
Original Source

Mapster includes a benchmark project in src/Benchmark that compares the local Mapster build with AutoMapper, Facet, and Mapperly across several object shapes.

This page is a May 2026 snapshot of those benchmarks. Treat the numbers as a comparison point for this environment and benchmark configuration rather than an absolute guarantee for every machine or application.

How to read the tables

  • Mean is the total time for one BenchmarkDotNet benchmark invocation. Each invocation runs a manual hot loop with MapOperations = 1,000,000.
  • Ns/Map normalizes Mean to the approximate cost of one logical mapping call.
  • Allocated is the memory allocated by one benchmark invocation.
  • Bytes/Map normalizes Allocated to one logical mapping call.
  • Ratio and Alloc Ratio are relative to the default Mapster benchmark in the same scenario.
  • TotalAllTypes runs three mapping scenarios in one benchmark invocation, so its Ns/Map and Bytes/Map values are divided by MapOperations * 3.

Benchmark scenarios

FlatTypes

FlatTypes maps Person -> PersonDTO. It is a flat DTO shape: simple property-to-property copy, no nested objects, and no collections. This scenario mostly highlights mapper call overhead, generated IL quality, and allocation rate for a best-case DTO.

ComplexTypes

ComplexTypes maps Customer -> CustomerDTO. It includes nested address mapping, array/list shape changes, and a flattening rule (AddressCity <- Address.City). This scenario is useful for typical DTOs that combine nested objects, collections, and a small amount of custom member mapping.

RecursiveTypes

RecursiveTypes maps Foo -> FooDTO. The type shape is self-recursive: a Foo can contain another Foo, an enumerable of Foo, and an array of Foo. The sample data does not intentionally create a back-reference cycle, but the mapping graph is deeper and allocates more nested DTOs than the flat or customer scenarios.

TotalAllTypes

TotalAllTypes runs FlatTypes, RecursiveTypes, and ComplexTypes sequentially in one benchmark method. Mean is therefore the total batch time for all three scenarios; use Ns/Map and Bytes/Map for normalized per-map interpretation.

Compared methods

  • Mapster uses the default Mapster expression compiler.
  • Mapster (Roslyn) uses the Roslyn/debug-info compiler path.
  • Mapster (FEC) uses FastExpressionCompiler.
  • Mapster (Codegen) uses generated mapping code.
  • AutoMapper, Facet, and Mapperly are included as external comparison points.
  • Facet (Compiled Projection) uses Facet's compiled projection path, which can behave very differently from the constructor path depending on the object shape.

Results

FlatTypes

ScenarioMethodMapOperationsMeanStdDevErrorNs/MapRatioGen0AllocatedAlloc RatioBytes/Map
FlatTypesMapster 10.0.810000006.849 ms0.6851 ms1.0358 ms6.8491.01478176.29 MB1.0080
FlatTypesMapster 10.0.8 (Roslyn)10000006.579 ms0.2782 ms0.4206 ms6.5790.97478176.29 MB1.0080
FlatTypesMapster 10.0.8 (FEC)10000006.549 ms0.9130 ms1.3803 ms6.5490.97478176.29 MB1.0080
FlatTypesMapster 10.0.8 (Codegen)10000005.868 ms0.3266 ms0.5488 ms5.8680.86478176.29 MB1.0080
FlatTypesAutoMapper 14.0.0100000029.645 ms0.8963 ms1.5062 ms29.6454.37475076.29 MB1.0080
FlatTypesFacet 6.5.510000007.801 ms1.0231 ms1.5467 ms7.8011.158601137.33 MB1.80144
FlatTypesFacet 6.5.5 (Compiled Projection)10000005.508 ms0.7064 ms1.0679 ms5.5080.81478176.29 MB1.0080
FlatTypesMapperly 4.3.110000006.521 ms0.8369 ms1.2652 ms6.5210.96478176.29 MB1.0080

ComplexTypes

ScenarioMethodMapOperationsMeanStdDevErrorNs/MapRatioGen0Gen1AllocatedAlloc RatioBytes/Map
ComplexTypesMapster 10.0.8100000078.59 ms1.519 ms2.553 ms78.5861.0028111-450.13 MB1.00472
ComplexTypesMapster 10.0.8 (Roslyn)100000053.48 ms1.760 ms2.958 ms53.4750.6825818-411.99 MB0.92432
ComplexTypesMapster 10.0.8 (FEC)100000069.29 ms1.539 ms2.326 ms69.2880.8828200-450.13 MB1.00472
ComplexTypesMapster 10.0.8 (Codegen)100000051.86 ms2.514 ms3.801 ms51.8630.6625750-411.99 MB0.92432
ComplexTypesAutoMapper 14.0.01000000112.27 ms4.516 ms7.590 ms112.2701.4329142-465.39 MB1.03488
ComplexTypesFacet 6.5.51000000446.72 ms51.706 ms78.172 ms446.7255.691750005002792.36 MB6.202928
ComplexTypesFacet 6.5.5 (Compiled Projection)1000000678.87 ms42.646 ms64.474 ms678.8688.6444000-709.53 MB1.58744
ComplexTypesMapperly 4.3.1100000052.81 ms1.134 ms1.714 ms52.8120.6725769-411.99 MB0.92432

RecursiveTypes

ScenarioMethodMapOperationsMeanStdDevErrorNs/MapRatioGen0Gen1AllocatedAlloc RatioBytes/Map
RecursiveTypesMapster 10.0.81000000404.49 ms63.593 ms96.14 ms404.4861.0249000-793.46 MB1.00832
RecursiveTypesMapster 10.0.8 (Roslyn)1000000383.00 ms34.563 ms52.25 ms382.9990.9749000-793.46 MB1.00832
RecursiveTypesMapster 10.0.8 (FEC)100000084.82 ms10.777 ms16.29 ms84.8160.2145875125732.42 MB0.92768
RecursiveTypesMapster 10.0.8 (Codegen)100000082.81 ms11.104 ms16.79 ms82.8060.2149625125793.46 MB1.00832
RecursiveTypesAutoMapper 14.0.01000000585.42 ms88.660 ms134.04 ms585.4251.4816800010002693.18 MB3.392824
RecursiveTypesFacet 6.5.51000000302.24 ms9.444 ms18.06 ms302.2410.761500006662395.63 MB3.022512
RecursiveTypesFacet 6.5.5 (Compiled Projection)1000000708.77 ms58.207 ms88.00 ms708.7701.7973000-1174.93 MB1.481232
RecursiveTypesMapperly 4.3.11000000116.05 ms16.639 ms25.16 ms116.0550.29688331661098.63 MB1.381152

TotalAllTypes

ScenarioMethodMapOperationsMeanStdDevErrorNs/MapRatioGen0Gen1AllocatedAlloc RatioBytes/Map
TotalAllTypesMapster 10.0.81000000413.9 ms16.88 ms25.52 ms137.971.0082000-1.29 GB1.00461
TotalAllTypesMapster 10.0.8 (Roslyn)1000000546.4 ms29.01 ms43.86 ms182.121.3280000-1.25 GB0.97448
TotalAllTypesMapster 10.0.8 (FEC)1000000155.7 ms24.48 ms37.01 ms51.910.3878800-1.23 GB0.95440
TotalAllTypesMapster 10.0.8 (Codegen)1000000117.4 ms8.56 ms12.94 ms39.140.2880250-1.25 GB0.97448
TotalAllTypesAutoMapper 14.0.01000000681.4 ms76.25 ms115.27 ms227.131.6520200010003.16 GB2.451130
TotalAllTypesFacet 6.5.51000000677.4 ms33.30 ms55.96 ms225.801.6432900010005.14 GB3.991840
TotalAllTypesFacet 6.5.5 (Compiled Projection)10000001,337.4 ms42.95 ms64.94 ms445.813.24122000-1.91 GB1.49685
TotalAllTypesMapperly 4.3.11000000141.5 ms3.04 ms5.81 ms47.100.34992502501.55 GB1.20554

Interpretation notes

  • The fastest method depends on the object shape. Flat DTOs mostly measure low-level call overhead; recursive graphs and collection-heavy DTOs shift the bottleneck toward nested object creation and collection mapping.
  • Facet constructor and compiled-projection paths are shown separately because they exercise different APIs and can trade CPU time for allocation behavior differently across scenarios.