Benchmark three popular .NET object mappers using BenchmarkDotNet — compare mapping speed, memory allocation, and throughput with real-world Order → OrderDto scenarios.
If this sample saved you time, consider joining our Patreon community. You'll get exclusive .NET tutorials, premium code samples, and early access to new content — all for the price of a coffee.
👉 Join CodingDroplets on Patreon
Prefer a one-time tip? Buy us a coffee ☕
- Performance characteristics of reflection-based (AutoMapper), configuration-based (Mapster), and source-generated (Mapperly) mapping approaches
- How to set up BenchmarkDotNet for accurate microbenchmarking
- Memory allocation differences between the three mappers
- When to choose each mapper based on throughput and latency requirements
- Real-world mapping scenarios: simple objects, collections, and nested object graphs
Source Models (Order, Customer, OrderItem)
│
│ AutoMapper (Reflection + Expression Trees)
│ Mapster (Configuration + Compilation)
│ Mapperly (Source Generation - IL Emit)
▼
Destination DTOs (OrderDto, CustomerDto, OrderItemDto)
│
│ BenchmarkDotNet Measurement
▼
Results: Latency (ns), Memory (B), Throughput (ops/s)
| Mapper | Mapping Approach | Typical Latency (ns) | Memory Allocation | Best For |
|---|---|---|---|---|
| AutoMapper | Reflection + Expression Trees | ~350 ns | Moderate | Complex mapping scenarios, legacy projects, rapid development |
| Mapster | Configuration + Runtime Compilation | ~120 ns | Low | Balance of flexibility and performance, medium-traffic apps |
| Mapperly | Source Generation (IL Emit) | ~45 ns | Minimal | High-performance APIs, latency-sensitive systems, .NET 10+ |
dotnet-object-mapper-benchmark/
├── dotnet-object-mapper-benchmark.sln
└── src/
└── ObjectMapperBenchmark/
├── ObjectMapperBenchmark.csproj
├── Program.cs
├── Models/
│ ├── Order.cs
│ ├── OrderItem.cs
│ ├── Customer.cs
│ ├── OrderDto.cs
│ ├── OrderItemDto.cs
│ └── CustomerDto.cs
├── Mappers/
│ ├── AutoMapperProfile.cs
│ ├── MapsterConfig.cs
│ └── OrderMapper.cs
└── Benchmarks/
├── SimpleMapBenchmark.cs
├── CollectionMapBenchmark.cs
└── NestedMapBenchmark.cs
- .NET SDK 10.0 or later
- IDE: Visual Studio 2022 / VS Code with C# Dev Kit
- OS: Windows, Linux, or macOS
# Clone the repository
git clone https://github.com/codingdroplets/dotnet-object-mapper-benchmark.git
cd dotnet-object-mapper-benchmark
# Restore packages
dotnet restore
# Build in Release mode
dotnet build -c Release
# Run all benchmarks
dotnet run -c ReleaseThe benchmark results will be displayed in the console and exported to a BenchmarkDotNet.Artifacts folder with detailed reports.
- Benchmark Setup — Each benchmark class uses
[GlobalSetup]to initialize the mapper once, ensuring fair comparison. - Three Benchmark Methods — Each mapper gets its own method with
[Benchmark]attribute; AutoMapper is marked as[Baseline]. - MemoryDiagnoser — Captures memory allocation per operation to identify GC pressure.
- Orderer — Results are sorted from fastest to slowest for easy comparison.
- SimpleMapBenchmark — Maps a single Order object with nested Customer and 3 OrderItems.
- CollectionMapBenchmark — Maps a
List<Order>containing 100 orders, testing bulk mapping efficiency. - NestedMapBenchmark — Maps a complex Order with 5 OrderItems, stressing deep object graph traversal.
Sample results (your numbers will vary based on hardware and SDK version):
| Mapper | Mean (ns) | Error (ns) | StdDev (ns) | Memory (B) |
|---|---|---|---|---|
| Mapperly | 45.2 | ±2.1 | 2.5 | 48 |
| Mapster | 121.8 | ±4.3 | 5.1 | 128 |
| AutoMapper | 348.7 | ±12.5 | 14.2 | 512 |
⚠️ Note: These are illustrative placeholder values. Run the benchmarks on your machine to get actual numbers.
| Concept | AutoMapper | Mapster | Mapperly |
|---|---|---|---|
| Mechanism | Runtime reflection + compiled expressions | Configuration + runtime compilation | IL generation at compile-time |
| Startup Cost | High (scan assemblies, build mappings) | Medium (compile mappings on first use) | None (code already generated) |
| Per-Call Overhead | Medium (invoke expression) | Low (invoke compiled delegate) | Minimal (direct method call) |
| Memory Footprint | Higher (expression trees) | Moderate (compiled delegates) | Minimal (no runtime metadata) |
| Migration Effort | Low (convention-based) | Low-Medium (configuration) | Medium (write/CQ-mapped classes) |
- Choose AutoMapper if you need rapid development, complex custom transformations, or are working with a legacy codebase that already uses it.
- Choose Mapster if you want better performance without abandoning configuration flexibility, or if you target frameworks without source generator support.
- Choose Mapperly if you need maximum performance and minimal allocations, are on .NET 10+, and are okay with writing explicit mapper classes.
| Technology | Version | Purpose |
|---|---|---|
| .NET | 10.0 | Target framework |
| C# | 12.0+ | Language |
| BenchmarkDotNet | 0.15.8 | Benchmarking engine |
| AutoMapper | 16.1.1 | Reflection-based object mapper |
| Mapster | 10.0.6 | Configuration-based object mapper |
| Riok.Mapperly | 4.3.1 | Source-generated object mapper |
- BenchmarkDotNet Documentation
- AutoMapper Official Site
- Mapster GitHub Repository
- Riok.Mapperly GitHub
MIT License — see LICENSE for details.
| Platform | Link |
|---|---|
| 🌐 Website | https://codingdroplets.com/ |
| 📺 YouTube | https://www.youtube.com/@CodingDroplets |
| 🎁 Patreon | https://www.patreon.com/CodingDroplets |
| ☕ Buy Me a Coffee | https://buymeacoffee.com/codingdroplets |
| 💻 GitHub | http://github.com/codingdroplets/ |
Want more samples like this? Support us on Patreon or buy us a coffee ☕ — every bit helps keep the content coming!
📖 Read the full guide: AutoMapper vs Mapster vs Mapperly in .NET