diff --git a/src/Benchmark.Development/Benchmark.Development.csproj b/src/Benchmark.Development/Benchmark.Development.csproj
new file mode 100644
index 00000000..572bdf29
--- /dev/null
+++ b/src/Benchmark.Development/Benchmark.Development.csproj
@@ -0,0 +1,26 @@
+
+
+
+ Exe
+ net10.0
+ true
+ enable
+ enable
+ True
+ Benchmark.Development.snk
+ False
+ 7.4.0
+ 12.0
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Benchmark.Development/Benchmark.Development.snk b/src/Benchmark.Development/Benchmark.Development.snk
new file mode 100644
index 00000000..beae8ece
Binary files /dev/null and b/src/Benchmark.Development/Benchmark.Development.snk differ
diff --git a/src/Benchmark.Development/Benchmarks/Config.cs b/src/Benchmark.Development/Benchmarks/Config.cs
new file mode 100644
index 00000000..554581ab
--- /dev/null
+++ b/src/Benchmark.Development/Benchmarks/Config.cs
@@ -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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Benchmark.Development/Benchmarks/TestAll.cs b/src/Benchmark.Development/Benchmarks/TestAll.cs
new file mode 100644
index 00000000..b3e28a76
--- /dev/null
+++ b/src/Benchmark.Development/Benchmarks/TestAll.cs
@@ -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(_fooInstance, Iterations);
+ TestAdaptHelper.TestMapsterAdapter(_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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Benchmark.Development/Benchmarks/TestComplexTypes.cs b/src/Benchmark.Development/Benchmarks/TestComplexTypes.cs
new file mode 100644
index 00000000..62d7a764
--- /dev/null
+++ b/src/Benchmark.Development/Benchmarks/TestComplexTypes.cs
@@ -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(_customerInstance, Iterations);
+ }
+
+ [GlobalSetup(Target = nameof(MapsterTest))]
+ public void SetupMapster()
+ {
+ _customerInstance = TestAdaptHelper.SetupCustomerInstance();
+ TestAdaptHelper.ConfigureMapster(_customerInstance, MapsterCompilerType.Default);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Benchmark.Development/Benchmarks/TestSimpleTypes.cs b/src/Benchmark.Development/Benchmarks/TestSimpleTypes.cs
new file mode 100644
index 00000000..8678a8ec
--- /dev/null
+++ b/src/Benchmark.Development/Benchmarks/TestSimpleTypes.cs
@@ -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(_fooInstance, Iterations);
+ }
+
+ [GlobalSetup(Target = nameof(MapsterTest))]
+ public void SetupMapster()
+ {
+ _fooInstance = TestAdaptHelper.SetupFooInstance();
+ TestAdaptHelper.ConfigureMapster(_fooInstance, MapsterCompilerType.Default);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Benchmark.Development/Classes/Customer.cs b/src/Benchmark.Development/Classes/Customer.cs
new file mode 100644
index 00000000..5fac9cef
--- /dev/null
+++ b/src/Benchmark.Development/Classes/Customer.cs
@@ -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 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 WorkAddresses { get; set; }
+ public string AddressCity { get; set; }
+ }
+}
diff --git a/src/Benchmark.Development/Classes/Foo.cs b/src/Benchmark.Development/Classes/Foo.cs
new file mode 100644
index 00000000..063541b8
--- /dev/null
+++ b/src/Benchmark.Development/Classes/Foo.cs
@@ -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 Foos { get; set; }
+
+ public Foo[] FooArr { get; set; }
+
+ public int[] IntArr { get; set; }
+
+ public IEnumerable Ints { get; set; }
+ }
+}
diff --git a/src/Benchmark.Development/Directory.Build.props b/src/Benchmark.Development/Directory.Build.props
new file mode 100644
index 00000000..8c415f63
--- /dev/null
+++ b/src/Benchmark.Development/Directory.Build.props
@@ -0,0 +1,18 @@
+
+
+
+ false
+
+
+
+ chaowlert;eric_swann;andrerav
+ Copyright (c) $([System.DateTime]::Now.ToString(`yyyy`)) Chaowlert Chaisrichalermpol, Eric Swann, Andreas Ravnestad
+ false
+
+ MIT
+ false
+ true
+ false
+ 12
+
+
\ No newline at end of file
diff --git a/src/Benchmark.Development/Program.cs b/src/Benchmark.Development/Program.cs
new file mode 100644
index 00000000..32e641ed
--- /dev/null
+++ b/src/Benchmark.Development/Program.cs
@@ -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());
diff --git a/src/Benchmark.Development/TestAdaptHelper.cs b/src/Benchmark.Development/TestAdaptHelper.cs
new file mode 100644
index 00000000..c6e06739
--- /dev/null
+++ b/src/Benchmark.Development/TestAdaptHelper.cs
@@ -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
+ {
+ 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
+ {
+ 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 _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(); //exercise
+ }
+
+ public static void ConfigureMapster(Customer customerInstance, MapsterCompilerType type)
+ {
+ SetupCompiler(type);
+ TypeAdapterConfig.GlobalSettings.Compile(typeof(Customer), typeof(CustomerDTO)); //recompile
+ customerInstance.Adapt(); //exercise
+ }
+
+ public static void TestMapsterAdapter(TSrc item, int iterations)
+ where TSrc : class
+ where TDest : class, new()
+ {
+ Loop(item, get => get.Adapt(), iterations);
+ }
+
+ private static void Loop(T item, Action action, int iterations)
+ {
+ for (var i = 0; i < iterations; i++) action(item);
+ }
+ }
+
+ public enum MapsterCompilerType
+ {
+ Default,
+ Roslyn,
+ FEC,
+ }
+}
\ No newline at end of file
diff --git a/src/Mapster.sln b/src/Mapster.sln
index befd616f..f55ef5d1 100644
--- a/src/Mapster.sln
+++ b/src/Mapster.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.0.32014.148
+# Visual Studio Version 18
+VisualStudioVersion = 18.1.11304.174 d18.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A5580F9D-0F5F-4224-980F-7824536A627D}"
ProjectSection(SolutionItems) = preProject
@@ -63,6 +63,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TemplateTest", "TemplateTes
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mapster.Tool.Tests", "Mapster.Tool.Tests\Mapster.Tool.Tests.csproj", "{E64E9CEB-8FB2-4012-BBA8-4C2B99FD54C1}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmark.Development", "Benchmark.Development\Benchmark.Development.csproj", "{5F29425E-DFC6-48C2-945A-FC5D91260C07}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -161,6 +163,10 @@ Global
{E64E9CEB-8FB2-4012-BBA8-4C2B99FD54C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E64E9CEB-8FB2-4012-BBA8-4C2B99FD54C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E64E9CEB-8FB2-4012-BBA8-4C2B99FD54C1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5F29425E-DFC6-48C2-945A-FC5D91260C07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5F29425E-DFC6-48C2-945A-FC5D91260C07}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5F29425E-DFC6-48C2-945A-FC5D91260C07}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5F29425E-DFC6-48C2-945A-FC5D91260C07}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE