DEV Community

Steven Kamwaza
Steven Kamwaza

Posted on

Twinify 1.0.2: A Look at the Latest Performance Improvements

Over the past few weeks, the performance and memory efficiency of Twinify has been improved, twinify is an open-source object-to-object mapping library for .NET.

The latest release, Twinify 1.0.2, brings some encouraging improvements compared with the initial 1.0.0 release.

I also wanted to keep the benchmarking honest, so the tests include AutoMapper 16.2.0 as a reference point.

Twinify is designed to make object mapping simple, while supporting common scenarios such as nested objects, collections, flattening, constructor mapping, and custom mappings.

The Benchmark

The benchmark uses:

  • .NET 10
  • BenchmarkDotNet 0.15.8
  • Windows 11
  • Intel Core i7-1355U
  • Twinify 1.0.0
  • Twinify 1.0.2
  • AutoMapper 16.2.0

The object graph being mapped is not just a simple flat object.

The benchmark maps:

User
 ├── Address
 └── Orders
      ├── Order
      │    └── OrderItems
      └── Order
           └── OrderItems
Enter fullscreen mode Exit fullscreen mode

Two scenarios are tested:

  1. Mapping a single User to UserDto
  2. Mapping 1,000 users to UserDto

Memory allocation and GC activity are also measured using BenchmarkDotNet's MemoryDiagnoser.

Performance Progress

Here are the results.

Scenario Metric Twinify 1.0.0 Twinify 1.0.2 AutoMapper 16.2.0
Single User Mean 3.819 μs 4.087 μs 1.066 μs
Single User Allocated 3,304 B 1,848 B 848 B
1,000 Users Mean 4,420.174 μs 2,420.444 μs 1,108.267 μs
1,000 Users Allocated 3,320,120 B 1,864,120 B 864,120 B
1,000 Users Gen0 523.4375 296.8750 136.7188
1,000 Users Gen1 242.1875 171.8750 78.1250

45% Faster Bulk Mapping

The biggest improvement can be seen when mapping 1,000 users.

Twinify 1.0.0:

4,420.174 μs
Enter fullscreen mode Exit fullscreen mode

Twinify 1.0.2:

2,420.444 μs
Enter fullscreen mode Exit fullscreen mode

That's approximately a 45% reduction in execution time.

The performance gap with AutoMapper has also become much smaller.

AutoMapper 16.2.0 completes the same benchmark in:

1,108.267 μs
Enter fullscreen mode Exit fullscreen mode

There is still a gap, but the improvement from the initial Twinify release is significant.

44% Less Memory Allocation

Performance isn't only about execution time.

For the 1,000-user benchmark:

Twinify 1.0.0
3,320,120 B

Twinify 1.0.2
1,864,120 B
Enter fullscreen mode Exit fullscreen mode

That's approximately 44% less memory allocation.

This is particularly important for applications performing large numbers of mappings because unnecessary allocations can increase GC pressure.

Reduced GC Pressure

The reduction in allocations is also reflected in the GC measurements.

For the 1,000-user benchmark, Gen0 collections dropped from:

523.4375 → 296.8750
Enter fullscreen mode Exit fullscreen mode

That's approximately a 43% reduction.

Gen1 also decreased:

242.1875 → 171.8750
Enter fullscreen mode Exit fullscreen mode

or approximately 29%.

These improvements are encouraging because they show that the memory optimizations are not simply reflected in the allocation column; they are also reducing GC activity.

What About AutoMapper?

AutoMapper 16.2.0 is still ahead in this benchmark.

For 1,000 users:

Twinify 1.0.2   2,420.444 μs
AutoMapper      1,108.267 μs
Enter fullscreen mode Exit fullscreen mode

And in allocations:

Twinify 1.0.2   1,864,120 B
AutoMapper        864,120 B
Enter fullscreen mode Exit fullscreen mode

So there is still work to do.

What's Next?

The next optimization targets are clear.

I'm particularly interested in reducing:

  • Mapping execution overhead
  • Allocations during nested and collection mapping
  • Reflection or dynamic dispatch on the hot path
  • Temporary objects and collections
  • GC pressure during large mapping operations

The current results already show that there is plenty of room for optimization.

The next milestone is to continue closing the gap while keeping Twinify's API simple and predictable.

Why Benchmark?

One of the things I want to emphasize with Twinify is that performance claims should be backed by reproducible benchmarks.

Rather than simply saying that a mapper is "fast", I'm trying to track actual changes between releases.

For example:

Twinify 1.0.0
      ↓
4.42 ms / 1,000 users
      ↓
Twinify 1.0.2
      ↓
2.42 ms / 1,000 users
Enter fullscreen mode Exit fullscreen mode

That gives future releases something concrete to improve against.

Try Twinify

Twinify is available on NuGet and the documentation contains examples covering profiles, nested mappings, collections, dependency injection, and other mapping scenarios.

Documentation:
Twinify Documentation

NuGet:
Twinify on NuGet

The current NuGet listing identifies 1.0.2 as the latest Twinify release.

Final Thoughts

Twinify 1.0.2 is another step forward.

The current benchmark shows:

  • 🚀 45% faster bulk mapping compared with Twinify 1.0.0
  • 💾 44% less memory allocation
  • ♻️ 43% fewer Gen0 collections
  • 📈 A significantly smaller performance gap compared with the initial release

There is still a lot of optimization ahead, and that's part of the fun.

I'm looking forward to seeing how far Twinify can go.

If you're interested in .NET object mapping, performance optimization, or open-source development, I'd love to hear your thoughts and feedback.

Twinify — Object Mapping Made Simple.

dotnet #csharp #opensource #performance

Top comments (0)