title: How to Improve Performance of C# Object Mapping Code
body: <p>How can I further improve the performance of the code below while still maintaining the public interface:</p>
  
  <pre><code>public interface IMapper&lt;in TSource, in TDestination&gt;
  {
      void Map(TSource source, TDestination destination);
  }
  
  public static TDestination Map&lt;TSource, TDestination&gt;(
      this IMapper&lt;TSource, TDestination&gt; translator,
      TSource source)
      where TDestination : new()
  {
      var destination = new TDestination();
      translator.Map(source, destination);
      return destination;
  }
  
  public static List&lt;TDestination&gt; MapList&lt;TSource, TDestination&gt;(
      this IMapper&lt;TSource, TDestination&gt; translator,
      List&lt;TSource&gt; source)
      where TDestination : new()
  {
      var destinationCollection = new List&lt;TDestination&gt;(source.Count);
      foreach (var sourceItem in source)
      {
          var destinationItem = translator.Map(sourceItem);
          destinationCollection.Add(destinationItem);
      }
      return destinationCollection;
  }
  </code></pre>
  
  <h1>Example Usage</h1>
  
  <pre><code>public class MapFrom { public string Property { get; set; } }
  
  public class MapTo { public string Property { get; set; } }
  
  public class Mapper : IMapper&lt;MapFrom, MapTo&gt;
  {
      public void Map(MapFrom source, MapTo destination)
      {
          destination.Property = source.Property;
      }
  }
  
  var mapper = new Mapper();
  var mapTo = mapper.Map(new MapFrom() { Property = "Foo" });
  var mapToList = mapper.MapList(
      new List&lt;MapFrom&gt;() 
      {
          new MapFrom() { Property = "Foo" } 
      });
  </code></pre>
  
  <h1>Current Benchmark</h1>
  
  <p>When I run a benchmark against a raw manual conversion, these are the numbers I get:</p>
  
  <pre><code>|             Method |  Job | Runtime |      Mean |     Error |    StdDev |       Min |       Max | Scaled | ScaledSD |  Gen 0 | Allocated |
  |------------------- |----- |-------- |----------:|----------:|----------:|----------:|----------:|-------:|---------:|-------:|----------:|
  |           Baseline |  Clr |     Clr |  1.969 us | 0.0354 us | 0.0332 us |  1.927 us |  2.027 us |   1.00 |     0.00 | 2.0523 |   6.31 KB |
  |  Mapper            |  Clr |     Clr |  9.016 us | 0.1753 us | 0.2019 us |  8.545 us |  9.419 us |   4.58 |     0.12 | 2.0447 |   6.31 KB |
  |           Baseline | Core |    Core |  1.820 us | 0.0346 us | 0.0355 us |  1.777 us |  1.902 us |   1.00 |     0.00 | 2.0542 |   6.31 KB |
  |  Mapper            | Core |    Core |  9.043 us | 0.1725 us | 0.1613 us |  8.764 us |  9.294 us |   4.97 |     0.13 | 2.0447 |   6.31 KB |
  </code></pre>
  
  <p>Here is the code for the baseline:</p>
  
  <pre><code>var mapTo = new MapTo() { Property = mapFrom.Property };
  var mapToCollection = new List&lt;MapTo&gt;(this.mapFrom.Count);
  foreach (var item in this.mapFrom)
  {
      destination.Add(new MapTo() { Property = item.Property });
  }
  </code></pre>
  
  <h1>Benchmark Code</h1>
  
  <p>I have a fully working project containing the mapper and Benchmark.NET project in the <a href="https://github.com/Dotnet-Boxed/Framework" rel="nofollow noreferrer">Dotnet-Boxed/Framework</a> GitHub repository. </p>