Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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