Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
86201b9
--Duplicate C:\Users\DocSv\source\repos\DocSvartz\Mapster\src\Benchma…
DocSvartz Dec 14, 2025
4f34280
--Restore C:\Users\DocSv\source\repos\DocSvartz\Mapster\src\Benchmark…
DocSvartz Dec 14, 2025
2b1e1e3
Copy C:\Users\DocSv\source\repos\DocSvartz\Mapster\src\Benchmark\Clas…
DocSvartz Dec 14, 2025
bd8c6dc
--Duplicate C:\Users\DocSv\source\repos\DocSvartz\Mapster\src\Benchma…
DocSvartz Dec 14, 2025
38efba5
--Restore C:\Users\DocSv\source\repos\DocSvartz\Mapster\src\Benchmark…
DocSvartz Dec 14, 2025
8cbed32
Copy C:\Users\DocSv\source\repos\DocSvartz\Mapster\src\Benchmark\Clas…
DocSvartz Dec 14, 2025
ef0c17f
--Duplicate C:\Users\DocSv\source\repos\DocSvartz\Mapster\src\Benchma…
DocSvartz Dec 14, 2025
80a981d
--Restore C:\Users\DocSv\source\repos\DocSvartz\Mapster\src\Benchmark…
DocSvartz Dec 14, 2025
c968970
Copy C:\Users\DocSv\source\repos\DocSvartz\Mapster\src\Benchmark\Benc…
DocSvartz Dec 14, 2025
c08e5e9
--Duplicate C:\Users\DocSv\source\repos\DocSvartz\Mapster\src\Benchma…
DocSvartz Dec 14, 2025
b2bbfca
--Restore C:\Users\DocSv\source\repos\DocSvartz\Mapster\src\Benchmark…
DocSvartz Dec 14, 2025
b38741f
Copy C:\Users\DocSv\source\repos\DocSvartz\Mapster\src\Benchmark\Benc…
DocSvartz Dec 14, 2025
7443373
--Duplicate C:\Users\DocSv\source\repos\DocSvartz\Mapster\src\Benchma…
DocSvartz Dec 14, 2025
191ce97
--Restore C:\Users\DocSv\source\repos\DocSvartz\Mapster\src\Benchmark…
DocSvartz Dec 14, 2025
0fb91ff
Copy C:\Users\DocSv\source\repos\DocSvartz\Mapster\src\Benchmark\Benc…
DocSvartz Dec 14, 2025
2b4ce19
--Duplicate C:\Users\DocSv\source\repos\DocSvartz\Mapster\src\Benchma…
DocSvartz Dec 14, 2025
430fa72
--Restore C:\Users\DocSv\source\repos\DocSvartz\Mapster\src\Benchmark…
DocSvartz Dec 14, 2025
4005efb
Copy C:\Users\DocSv\source\repos\DocSvartz\Mapster\src\Benchmark\Benc…
DocSvartz Dec 14, 2025
87dcfb4
--Duplicate C:\Users\DocSv\source\repos\DocSvartz\Mapster\src\Benchma…
DocSvartz Dec 14, 2025
0b2604d
--Restore C:\Users\DocSv\source\repos\DocSvartz\Mapster\src\Benchmark…
DocSvartz Dec 14, 2025
cc3fa01
Copy C:\Users\DocSv\source\repos\DocSvartz\Mapster\src\Benchmark\Test…
DocSvartz Dec 14, 2025
047bc78
add benchmark developers
DocSvartz Dec 14, 2025
e920394
fix benchmark config
DocSvartz Dec 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions src/Benchmark.Development/Benchmark.Development.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<CopyLocalLockFileAssemblies Condition=" '$(Configuration)'=='Debug' ">true</CopyLocalLockFileAssemblies>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>Benchmark.Development.snk</AssemblyOriginatorKeyFile>
<DelaySign>False</DelaySign>
<SciVersion Condition="'$(SciVersion)' == ''">7.4.0</SciVersion>
<LangVersion>12.0</LangVersion>
</PropertyGroup>

<ItemGroup>
<Folder Include="Benchmarks\" />
<Folder Include="Classes\" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.15.8" />
<PackageReference Include="Mapster" Version="$(SciVersion)" />
</ItemGroup>

</Project>
Binary file added src/Benchmark.Development/Benchmark.Development.snk
Binary file not shown.
54 changes: 54 additions & 0 deletions src/Benchmark.Development/Benchmarks/Config.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using BenchmarkDotNet.Columns;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Exporters;
using BenchmarkDotNet.Exporters.Csv;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Loggers;
using Perfolizer.Models;

namespace Benchmark.Benchmarks
{
public class Config : ManualConfig
{
public Config()
{
AddLogger(ConsoleLogger.Default);

AddExporter(CsvExporter.Default);
AddExporter(MarkdownExporter.GitHub);
AddExporter(HtmlExporter.Default);

AddDiagnoser(MemoryDiagnoser.Default);
AddColumn(TargetMethodColumn.Method);

AddColumn(JobCharacteristicColumn.AllColumns);
AddColumnProvider(DefaultColumnProviders.Params);
AddColumn(StatisticColumn.Mean);

AddColumn(StatisticColumn.StdDev);
AddColumn(StatisticColumn.Error);

AddColumn(BaselineRatioColumn.RatioMean);
AddColumnProvider(DefaultColumnProviders.Metrics);

string[] targetVersions = [
"7.4.0",
"9.0.0-pre01",
];

foreach (var version in targetVersions)
{
AddJob(Job.ShortRun
.WithLaunchCount(1)
.WithWarmupCount(2)
.WithIterationCount(10)
.WithMsBuildArguments($"/p:SciVersion={version}")
.WithId($"v{version}")
);
}

Options |= ConfigOptions.JoinSummary;
}
}
}
30 changes: 30 additions & 0 deletions src/Benchmark.Development/Benchmarks/TestAll.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using Benchmark.Classes;
using BenchmarkDotNet.Attributes;

namespace Benchmark.Benchmarks
{
public class TestAll
{
private Foo _fooInstance;
private Customer _customerInstance;

[Params(100_000)]//, 1_000_000)]
public int Iterations { get; set; }

[Benchmark]
public void MapsterTest()
{
TestAdaptHelper.TestMapsterAdapter<Foo, Foo>(_fooInstance, Iterations);
TestAdaptHelper.TestMapsterAdapter<Customer, CustomerDTO>(_customerInstance, Iterations);
}

[GlobalSetup(Target = nameof(MapsterTest))]
public void SetupMapster()
{
_fooInstance = TestAdaptHelper.SetupFooInstance();
_customerInstance = TestAdaptHelper.SetupCustomerInstance();
TestAdaptHelper.ConfigureMapster(_fooInstance, MapsterCompilerType.Default);
TestAdaptHelper.ConfigureMapster(_customerInstance, MapsterCompilerType.Default);
}
}
}
26 changes: 26 additions & 0 deletions src/Benchmark.Development/Benchmarks/TestComplexTypes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Benchmark.Classes;
using BenchmarkDotNet.Attributes;

namespace Benchmark.Benchmarks
{
public class TestComplexTypes
{
private Customer _customerInstance;

[Params(1000, 10_000, 100_000, 1_000_000)]
public int Iterations { get; set; }

[Benchmark]
public void MapsterTest()
{
TestAdaptHelper.TestMapsterAdapter<Customer, CustomerDTO>(_customerInstance, Iterations);
}

[GlobalSetup(Target = nameof(MapsterTest))]
public void SetupMapster()
{
_customerInstance = TestAdaptHelper.SetupCustomerInstance();
TestAdaptHelper.ConfigureMapster(_customerInstance, MapsterCompilerType.Default);
}
}
}
26 changes: 26 additions & 0 deletions src/Benchmark.Development/Benchmarks/TestSimpleTypes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Benchmark.Classes;
using BenchmarkDotNet.Attributes;

namespace Benchmark.Benchmarks
{
public class TestSimpleTypes
{
private Foo _fooInstance;

[Params(1000, 10_000, 100_000, 1_000_000)]
public int Iterations { get; set; }

[Benchmark]
public void MapsterTest()
{
TestAdaptHelper.TestMapsterAdapter<Foo, Foo>(_fooInstance, Iterations);
}

[GlobalSetup(Target = nameof(MapsterTest))]
public void SetupMapster()
{
_fooInstance = TestAdaptHelper.SetupFooInstance();
TestAdaptHelper.ConfigureMapster(_fooInstance, MapsterCompilerType.Default);
}
}
}
41 changes: 41 additions & 0 deletions src/Benchmark.Development/Classes/Customer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System.Collections.Generic;

namespace Benchmark.Classes
{
public class Address
{
public int Id { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string Country { get; set; }
}

public class AddressDTO
{
public int Id { get; set; }
public string City { get; set; }
public string Country { get; set; }
}

public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public decimal? Credit { get; set; }
public Address Address { get; set; }
public Address HomeAddress { get; set; }
public Address[] Addresses { get; set; }
public ICollection<Address> WorkAddresses { get; set; }
}

public class CustomerDTO
{
public int Id { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
public AddressDTO HomeAddress { get; set; }
public AddressDTO[] Addresses { get; set; }
public List<AddressDTO> WorkAddresses { get; set; }
public string AddressCity { get; set; }
}
}
32 changes: 32 additions & 0 deletions src/Benchmark.Development/Classes/Foo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;

namespace Benchmark.Classes
{
public class Foo
{
public string Name { get; set; }

public int Int32 { get; set; }

public long Int64 { set; get; }

public int? NullInt { get; set; }

public float Floatn { get; set; }

public double Doublen { get; set; }

public DateTime DateTime { get; set; }

public Foo Foo1 { get; set; }

public IEnumerable<Foo> Foos { get; set; }

public Foo[] FooArr { get; set; }

public int[] IntArr { get; set; }

public IEnumerable<int> Ints { get; set; }
}
}
18 changes: 18 additions & 0 deletions src/Benchmark.Development/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project>
<PropertyGroup>
<!-- Properties related to build/pack -->
<IsPackable>false</IsPackable>
</PropertyGroup>
<PropertyGroup>
<!-- Metadata -->
<Authors>chaowlert;eric_swann;andrerav</Authors>
<Copyright>Copyright (c) $([System.DateTime]::Now.ToString(`yyyy`)) Chaowlert Chaisrichalermpol, Eric Swann, Andreas Ravnestad</Copyright>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<PackageReleaseNotes></PackageReleaseNotes>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<SignAssembly>false</SignAssembly>
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
<IsPackable>false</IsPackable>
<LangVersion>12</LangVersion>
</PropertyGroup>
</Project>
11 changes: 11 additions & 0 deletions src/Benchmark.Development/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Benchmark.Benchmarks;
using BenchmarkDotNet.Running;

var switcher = new BenchmarkSwitcher(new[]
{
typeof(TestSimpleTypes),
typeof(TestComplexTypes),
typeof(TestAll),
});

switcher.Run(args, new Config());
105 changes: 105 additions & 0 deletions src/Benchmark.Development/TestAdaptHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using Benchmark.Classes;
using Mapster;
using System.Linq.Expressions;

namespace Benchmark
{
public static class TestAdaptHelper
{

public static Customer SetupCustomerInstance()
{
return new Customer
{
Address = new Address { City = "istanbul", Country = "turkey", Id = 1, Street = "istiklal cad." },
HomeAddress = new Address { City = "istanbul", Country = "turkey", Id = 2, Street = "istiklal cad." },
Id = 1,
Name = "Eduardo Najera",
Credit = 234.7m,
WorkAddresses = new List<Address>
{
new Address {City = "istanbul", Country = "turkey", Id = 5, Street = "istiklal cad."},
new Address {City = "izmir", Country = "turkey", Id = 6, Street = "konak"}
},
Addresses = new[]
{
new Address {City = "istanbul", Country = "turkey", Id = 3, Street = "istiklal cad."},
new Address {City = "izmir", Country = "turkey", Id = 4, Street = "konak"}
}
};
}

public static Foo SetupFooInstance()
{
return new Foo
{
Name = "foo",
Int32 = 12,
Int64 = 123123,
NullInt = 16,
DateTime = DateTime.Now,
Doublen = 2312112,
Foo1 = new Foo { Name = "foo one" },
Foos = new List<Foo>
{
new Foo {Name = "j1", Int64 = 123, NullInt = 321},
new Foo {Name = "j2", Int32 = 12345, NullInt = 54321},
new Foo {Name = "j3", Int32 = 12345, NullInt = 54321}
},
FooArr = new[]
{
new Foo {Name = "a1"},
new Foo {Name = "a2"},
new Foo {Name = "a3"}
},
IntArr = new[] { 1, 2, 3, 4, 5 },
Ints = new[] { 7, 8, 9 }
};
}

private static readonly Func<LambdaExpression, Delegate> _defaultCompiler = TypeAdapterConfig.GlobalSettings.Compiler;

private static void SetupCompiler(MapsterCompilerType type)
{
TypeAdapterConfig.GlobalSettings.Compiler = type switch
{
MapsterCompilerType.Default => _defaultCompiler,
// MapsterCompilerType.Roslyn => exp => exp.CompileWithDebugInfo(),
// MapsterCompilerType.FEC => exp => exp.CompileFast(),
_ => throw new ArgumentOutOfRangeException(nameof(type)),
};
}
public static void ConfigureMapster(Foo fooInstance, MapsterCompilerType type)
{
SetupCompiler(type);
TypeAdapterConfig.GlobalSettings.Compile(typeof(Foo), typeof(Foo)); //recompile
fooInstance.Adapt<Foo, Foo>(); //exercise
}

public static void ConfigureMapster(Customer customerInstance, MapsterCompilerType type)
{
SetupCompiler(type);
TypeAdapterConfig.GlobalSettings.Compile(typeof(Customer), typeof(CustomerDTO)); //recompile
customerInstance.Adapt<Customer, CustomerDTO>(); //exercise
}

public static void TestMapsterAdapter<TSrc, TDest>(TSrc item, int iterations)
where TSrc : class
where TDest : class, new()
{
Loop(item, get => get.Adapt<TSrc, TDest>(), iterations);
}

private static void Loop<T>(T item, Action<T> action, int iterations)
{
for (var i = 0; i < iterations; i++) action(item);
}
}

public enum MapsterCompilerType
{
Default,
Roslyn,
FEC,
}
}
Loading
Loading