Skip to content

Commit cc5559b

Browse files
authored
Refactor benchmarks scenarios for reuse as test scenarios (#144)
Modifications: * refactor: moved benchmarks scenarios to integrations tests common * test: add integration test with scenario for texas holdem poker * refactor: use new fluent API for building conditions * refactor: use Condition ctor on new integration test
1 parent 519ae6f commit cc5559b

28 files changed

Lines changed: 272 additions & 98 deletions
Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,55 @@
1+
using System.Runtime.InteropServices;
12
using BenchmarkDotNet.Attributes;
23
using BenchmarkDotNet.Configs;
34
using BenchmarkDotNet.Diagnosers;
5+
using BenchmarkDotNet.Diagnostics.Windows;
46
using BenchmarkDotNet.Exporters;
57
using BenchmarkDotNet.Jobs;
68
using BenchmarkDotNet.Running;
9+
using McMaster.Extensions.CommandLineUtils;
710

811
[assembly: SimpleJob(RuntimeMoniker.Net60)]
912

1013
internal static class Program
1114
{
12-
private static void Main(string[] args)
15+
private static int Main(string[] args)
1316
{
14-
Console.WriteLine("Starting benchmark tests.");
15-
Console.WriteLine();
17+
var app = new CommandLineApplication();
1618

17-
var manualConfig = ManualConfig.CreateMinimumViable();
18-
manualConfig.AddDiagnoser(MemoryDiagnoser.Default);
19-
manualConfig.AddHardwareCounters(HardwareCounter.BranchInstructions, HardwareCounter.BranchMispredictions);
20-
manualConfig.AddExporter(HtmlExporter.Default);
19+
app.HelpOption();
2120

22-
_ = BenchmarkRunner.Run(typeof(Program).Assembly, manualConfig);
21+
var artifactsPathOption = app.Option("-a|--artifacts-path <ARTIFACTS_PATH>", "Sets the artifacts path", CommandOptionType.SingleValue, config =>
22+
{
23+
config.DefaultValue = "artifacts";
24+
});
2325

24-
Console.WriteLine("Press any key to exit...");
25-
Console.Read();
26+
app.OnExecute(() =>
27+
{
28+
Console.WriteLine("Starting benchmark tests.");
29+
Console.WriteLine();
30+
31+
var manualConfig = ManualConfig.CreateMinimumViable();
32+
manualConfig.AddDiagnoser(MemoryDiagnoser.Default);
33+
34+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
35+
{
36+
manualConfig.AddHardwareCounters(HardwareCounter.BranchInstructions, HardwareCounter.BranchMispredictions);
37+
var etwProfilerConfig = new EtwProfilerConfig(cpuSampleIntervalInMilliseconds: 0.125f, performExtraBenchmarksRun: false);
38+
manualConfig.AddDiagnoser(new EtwProfiler(etwProfilerConfig));
39+
}
40+
41+
manualConfig.AddExporter(HtmlExporter.Default);
42+
manualConfig.WithOption(ConfigOptions.JoinSummary, true);
43+
44+
var artifactsPath = artifactsPathOption.Value();
45+
if (artifactsPath is not null or "")
46+
{
47+
manualConfig.WithArtifactsPath(artifactsPath);
48+
}
49+
50+
_ = BenchmarkRunner.Run(typeof(Program).Assembly, manualConfig);
51+
});
52+
53+
return app.Execute(args);
2654
}
2755
}
Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

3-
<PropertyGroup>
4-
<OutputType>Exe</OutputType>
5-
<TargetFrameworks>net6.0</TargetFrameworks>
6-
<ImplicitUsings>enable</ImplicitUsings>
7-
<Nullable>enable</Nullable>
8-
<LangVersion>10.0</LangVersion>
9-
</PropertyGroup>
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFrameworks>net6.0</TargetFrameworks>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
<LangVersion>10.0</LangVersion>
9+
<DebugType>pdbonly</DebugType>
10+
<DebugSymbols>true</DebugSymbols>
1011

11-
<ItemGroup>
12-
<PackageReference Include="BenchmarkDotNet" Version="0.13.5" />
13-
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
14-
</ItemGroup>
12+
</PropertyGroup>
1513

16-
<ItemGroup>
17-
<ProjectReference Include="..\..\src\Rules.Framework\Rules.Framework.csproj" />
18-
</ItemGroup>
14+
<ItemGroup>
15+
<PackageReference Include="BenchmarkDotNet" Version="0.13.5" />
16+
<PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" Version="0.13.5" />
17+
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="4.0.2" />
18+
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
19+
</ItemGroup>
1920

20-
</Project>
21+
<ItemGroup>
22+
<ProjectReference Include="..\..\src\Rules.Framework\Rules.Framework.csproj" />
23+
<ProjectReference Include="..\Rules.Framework.IntegrationTests.Common\Rules.Framework.IntegrationTests.Common.csproj" />
24+
</ItemGroup>
25+
</Project>

tests/Rules.Framework.BenchmarkTests/Tests/Benchmark1/Benchmark1.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ namespace Rules.Framework.BenchmarkTests.Tests.Benchmark1
88
[SkewnessColumn, KurtosisColumn]
99
public class Benchmark1 : IBenchmark
1010
{
11-
private readonly Benchmark1Data benchmarkData = new Benchmark1Data();
12-
private RulesEngine<ContentTypes, ConditionTypes> rulesEngine;
11+
private readonly Scenario6Data benchmarkData = new Scenario6Data();
12+
private RulesEngine<ContentTypes, ConditionTypes>? rulesEngine;
1313

1414
[ParamsAllValues]
1515
public bool EnableCompilation { get; set; }
1616

1717
[Benchmark]
1818
public async Task RunAsync()
1919
{
20-
await this.rulesEngine.MatchOneAsync(ContentTypes.ContentType1, this.benchmarkData.MatchDate, this.benchmarkData.Conditions).ConfigureAwait(false);
20+
await this.rulesEngine!.MatchOneAsync(ContentTypes.ContentType1, this.benchmarkData.MatchDate, this.benchmarkData.Conditions).ConfigureAwait(false);
2121
}
2222

2323
[GlobalSetup]

tests/Rules.Framework.BenchmarkTests/Tests/Benchmark2/Benchmark2.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ namespace Rules.Framework.BenchmarkTests.Tests.Benchmark2
88
[SkewnessColumn, KurtosisColumn]
99
public class Benchmark2 : IBenchmark
1010
{
11-
private readonly Benchmark2Data benchmarkData = new Benchmark2Data();
12-
private RulesEngine<ContentTypes, ConditionTypes> rulesEngine;
11+
private readonly Scenario7Data benchmarkData = new Scenario7Data();
12+
private RulesEngine<ContentTypes, ConditionTypes>? rulesEngine;
1313

1414
[ParamsAllValues]
1515
public bool EnableCompilation { get; set; }
1616

1717
[Benchmark]
1818
public async Task RunAsync()
1919
{
20-
await this.rulesEngine.MatchOneAsync(ContentTypes.Songs, this.benchmarkData.MatchDate, this.benchmarkData.Conditions).ConfigureAwait(false);
20+
await this.rulesEngine!.MatchOneAsync(ContentTypes.Songs, this.benchmarkData.MatchDate, this.benchmarkData.Conditions).ConfigureAwait(false);
2121
}
2222

2323
[GlobalSetup]

tests/Rules.Framework.BenchmarkTests/Tests/Benchmark3/Benchmark3.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ namespace Rules.Framework.BenchmarkTests.Tests.Benchmark3
88
[SkewnessColumn, KurtosisColumn]
99
public class Benchmark3 : IBenchmark
1010
{
11-
private readonly Benchmark3Data benchmarkData = new Benchmark3Data();
12-
private RulesEngine<ContentTypes, ConditionTypes> rulesEngine;
11+
private readonly Scenario8Data benchmarkData = new Scenario8Data();
12+
private RulesEngine<ContentTypes, ConditionTypes>? rulesEngine;
1313

1414
[ParamsAllValues]
1515
public bool EnableCompilation { get; set; }
1616

1717
[Benchmark]
1818
public async Task RunAsync()
1919
{
20-
await this.rulesEngine.MatchOneAsync(ContentTypes.TexasHoldemPokerSingleCombinations, this.benchmarkData.MatchDate, this.benchmarkData.Conditions).ConfigureAwait(false);
20+
await this.rulesEngine!.MatchOneAsync(ContentTypes.TexasHoldemPokerSingleCombinations, this.benchmarkData.MatchDate, this.benchmarkData.Conditions).ConfigureAwait(false);
2121
}
2222

2323
[GlobalSetup]

tests/Rules.Framework.IntegrationTests.Common/Rules.Framework.IntegrationTests.Common.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
<PropertyGroup>
44
<TargetFramework>netstandard2.1</TargetFramework>
55
<IsPackable>false</IsPackable>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
<LangVersion>10.0</LangVersion>
9+
<DebugType>pdbonly</DebugType>
10+
<DebugSymbols>true</DebugSymbols>
611
</PropertyGroup>
712

813
<ItemGroup>

tests/Rules.Framework.BenchmarkTests/Tests/IBenchmarkData.cs renamed to tests/Rules.Framework.IntegrationTests.Common/Scenarios/IScenarioData.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace Rules.Framework.BenchmarkTests.Tests
55
using Rules.Framework;
66
using Rules.Framework.Core;
77

8-
internal interface IBenchmarkData<TContentType, TConditionType>
8+
public interface IScenarioData<TContentType, TConditionType>
99
{
1010
IEnumerable<Condition<TConditionType>> Conditions { get; }
1111

tests/Rules.Framework.BenchmarkTests/Tests/Benchmark1/ConditionTypes.cs renamed to tests/Rules.Framework.IntegrationTests.Common/Scenarios/Scenario6/ConditionTypes.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
namespace Rules.Framework.BenchmarkTests.Tests.Benchmark1
22
{
3-
internal enum ConditionTypes
3+
public enum ConditionTypes
44
{
55
IntegerCondition = 1,
66
DecimalCondition = 2,

tests/Rules.Framework.BenchmarkTests/Tests/Benchmark1/ContentTypes.cs renamed to tests/Rules.Framework.IntegrationTests.Common/Scenarios/Scenario6/ContentTypes.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
namespace Rules.Framework.BenchmarkTests.Tests.Benchmark1
22
{
3-
internal enum ContentTypes
3+
public enum ContentTypes
44
{
55
ContentType1 = 1,
66
}

tests/Rules.Framework.BenchmarkTests/Tests/Benchmark1/Benchmark1Data.cs renamed to tests/Rules.Framework.IntegrationTests.Common/Scenarios/Scenario6/Scenario6Data.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace Rules.Framework.BenchmarkTests.Tests.Benchmark1
66
using Rules.Framework.Builder;
77
using Rules.Framework.Core;
88

9-
internal class Benchmark1Data : IBenchmarkData<ContentTypes, ConditionTypes>
9+
public class Scenario6Data : IScenarioData<ContentTypes, ConditionTypes>
1010
{
1111
public IEnumerable<Condition<ConditionTypes>> Conditions => new[] { new Condition<ConditionTypes> { Type = ConditionTypes.StringCondition, Value = "Let's benchmark this!" } };
1212

0 commit comments

Comments
 (0)