Skip to content

Commit 7b9c488

Browse files
committed
Create the Benchmark project
1 parent 73ea6c5 commit 7b9c488

File tree

5 files changed

+300
-0
lines changed

5 files changed

+300
-0
lines changed

RecursiveDataAnnotationsValidation.sln

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{3C
1515
EndProject
1616
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OptionsPatternMvc.Example", "examples\OptionsPatternMvc.Example\OptionsPatternMvc.Example.csproj", "{44EAF2F4-79FC-4F4A-9FB2-B7EC687AD01A}"
1717
EndProject
18+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmark", "benchmark", "{915ACCB0-876D-4B1C-9B73-7E9617D8B938}"
19+
EndProject
20+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmark", "benchmark\Benchmark\Benchmark.csproj", "{8E426092-EC8C-4779-981E-9ECC1160D350}"
21+
EndProject
1822
Global
1923
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2024
Debug|Any CPU = Debug|Any CPU
@@ -64,10 +68,23 @@ Global
6468
{44EAF2F4-79FC-4F4A-9FB2-B7EC687AD01A}.Release|x64.Build.0 = Release|Any CPU
6569
{44EAF2F4-79FC-4F4A-9FB2-B7EC687AD01A}.Release|x86.ActiveCfg = Release|Any CPU
6670
{44EAF2F4-79FC-4F4A-9FB2-B7EC687AD01A}.Release|x86.Build.0 = Release|Any CPU
71+
{8E426092-EC8C-4779-981E-9ECC1160D350}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
72+
{8E426092-EC8C-4779-981E-9ECC1160D350}.Debug|Any CPU.Build.0 = Debug|Any CPU
73+
{8E426092-EC8C-4779-981E-9ECC1160D350}.Debug|x64.ActiveCfg = Debug|Any CPU
74+
{8E426092-EC8C-4779-981E-9ECC1160D350}.Debug|x64.Build.0 = Debug|Any CPU
75+
{8E426092-EC8C-4779-981E-9ECC1160D350}.Debug|x86.ActiveCfg = Debug|Any CPU
76+
{8E426092-EC8C-4779-981E-9ECC1160D350}.Debug|x86.Build.0 = Debug|Any CPU
77+
{8E426092-EC8C-4779-981E-9ECC1160D350}.Release|Any CPU.ActiveCfg = Release|Any CPU
78+
{8E426092-EC8C-4779-981E-9ECC1160D350}.Release|Any CPU.Build.0 = Release|Any CPU
79+
{8E426092-EC8C-4779-981E-9ECC1160D350}.Release|x64.ActiveCfg = Release|Any CPU
80+
{8E426092-EC8C-4779-981E-9ECC1160D350}.Release|x64.Build.0 = Release|Any CPU
81+
{8E426092-EC8C-4779-981E-9ECC1160D350}.Release|x86.ActiveCfg = Release|Any CPU
82+
{8E426092-EC8C-4779-981E-9ECC1160D350}.Release|x86.Build.0 = Release|Any CPU
6783
EndGlobalSection
6884
GlobalSection(NestedProjects) = preSolution
6985
{46ED500F-D954-44AA-A954-5CB19BE826BF} = {C76F9B02-7770-4472-908A-464DA20B926C}
7086
{16880471-6ABA-4662-AD7F-CE13F4C0406B} = {BC73618A-E8A0-423E-ACD3-035F41ABA8CF}
7187
{44EAF2F4-79FC-4F4A-9FB2-B7EC687AD01A} = {3C77C185-A671-4F75-AE4F-B31E6B3F86C2}
88+
{8E426092-EC8C-4779-981E-9ECC1160D350} = {915ACCB0-876D-4B1C-9B73-7E9617D8B938}
7289
EndGlobalSection
7390
EndGlobal
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>netcoreapp3.1</TargetFramework>
6+
<ImplicitUsings>disable</ImplicitUsings>
7+
<Nullable>disable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="BenchmarkDotNet" Version="0.13.2" />
12+
</ItemGroup>
13+
14+
<ItemGroup>
15+
<ProjectReference Include="..\..\src\RecursiveDataAnnotationsValidation\RecursiveDataAnnotationsValidation.csproj" />
16+
<ProjectReference Include="..\..\test\RecursiveDataAnnotationsValidation.Tests\RecursiveDataAnnotationsValidation.Tests.csproj" />
17+
</ItemGroup>
18+
19+
</Project>

benchmark/Benchmark/Benchmarks.cs

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
using System.Collections.Generic;
2+
using System.ComponentModel.DataAnnotations;
3+
using System.Linq;
4+
using BenchmarkDotNet.Attributes;
5+
using RecursiveDataAnnotationsValidation;
6+
using RecursiveDataAnnotationsValidation.Tests.TestModels;
7+
8+
namespace Benchmark
9+
{
10+
public class Benchmarks
11+
{
12+
private static readonly IRecursiveDataAnnotationValidator _sut = new RecursiveDataAnnotationValidator();
13+
14+
#region EnumerableExample
15+
16+
private static readonly EnumerableExample EnumerableExamplePassesAllValidationNoChildren = new EnumerableExample
17+
{
18+
Name = "Passes all",
19+
Age = 75,
20+
Items = new List<ItemExample>(),
21+
ItemsList = new List<ItemExample>(),
22+
ItemsCollection = new List<ItemExample>(),
23+
};
24+
25+
[Benchmark]
26+
public bool EnumerableExample_PassesAllValidation_NoChildren()
27+
{
28+
var validationResults = new List<ValidationResult>();
29+
var isValid =
30+
_sut.TryValidateObjectRecursive(EnumerableExamplePassesAllValidationNoChildren, validationResults);
31+
return isValid && validationResults.Any() == false;
32+
}
33+
34+
private static readonly EnumerableExample EnumerableExamplePassesAllValidationAllChildren =
35+
new EnumerableExample
36+
{
37+
Name = "Passes all",
38+
Age = 75,
39+
Items = new List<ItemExample>
40+
{
41+
new ItemExample
42+
{
43+
Name = "Child 1",
44+
SimpleA = new SimpleExample
45+
{
46+
IntegerA = 125,
47+
StringB = "child-1-stringB",
48+
BoolC = true,
49+
ExampleEnumD = ExampleEnum.ValueC
50+
}
51+
},
52+
new ItemExample
53+
{
54+
Name = "Child 2",
55+
SimpleA = new SimpleExample
56+
{
57+
IntegerA = 15,
58+
StringB = "child-2-string-abc",
59+
BoolC = false,
60+
ExampleEnumD = ExampleEnum.ValueA
61+
}
62+
}
63+
},
64+
ItemsList = new List<ItemExample>
65+
{
66+
new ItemExample
67+
{
68+
Name = "Child 1L",
69+
SimpleA = new SimpleExample
70+
{
71+
IntegerA = 123,
72+
StringB = "child-1L-stringB",
73+
BoolC = true,
74+
ExampleEnumD = ExampleEnum.ValueC
75+
}
76+
},
77+
new ItemExample
78+
{
79+
Name = "Child 2L",
80+
SimpleA = new SimpleExample
81+
{
82+
IntegerA = 75,
83+
StringB = "child-2L-string-abc",
84+
BoolC = false,
85+
ExampleEnumD = ExampleEnum.ValueA
86+
}
87+
}
88+
},
89+
ItemsCollection = new List<ItemExample>
90+
{
91+
new ItemExample
92+
{
93+
Name = "Child 1C",
94+
SimpleA = new SimpleExample
95+
{
96+
IntegerA = 25,
97+
StringB = "child-1C-stringB",
98+
BoolC = true,
99+
ExampleEnumD = ExampleEnum.ValueC
100+
}
101+
},
102+
new ItemExample
103+
{
104+
Name = "Child 2C",
105+
SimpleA = new SimpleExample
106+
{
107+
IntegerA = 120,
108+
StringB = "child-2C-string-abc",
109+
BoolC = false,
110+
ExampleEnumD = ExampleEnum.ValueA
111+
}
112+
}
113+
}
114+
};
115+
116+
[Benchmark]
117+
public bool EnumerableExample_PassesAllValidation_AllChildren()
118+
{
119+
var validationResults = new List<ValidationResult>();
120+
var isValid =
121+
_sut.TryValidateObjectRecursive(EnumerableExamplePassesAllValidationAllChildren, validationResults);
122+
return isValid && validationResults.Any() == false;
123+
}
124+
125+
#endregion
126+
127+
#region RecursionExample
128+
129+
private static readonly RecursionExample RecursionExamplePassesAllValidation = new RecursionExample
130+
{
131+
Name = "Recursion1",
132+
BooleanA = false,
133+
Recursion = new RecursionExample
134+
{
135+
Name = "Recursion1.Inner1",
136+
BooleanA = true,
137+
Recursion = null
138+
}
139+
};
140+
141+
public Benchmarks()
142+
{
143+
RecursionExamplePassesAllValidation.Recursion.Recursion = RecursionExamplePassesAllValidation.Recursion;
144+
}
145+
146+
[Benchmark]
147+
public bool RecursionExample_PassesAllValidation()
148+
{
149+
var validationResults = new List<ValidationResult>();
150+
var isValid = _sut.TryValidateObjectRecursive(RecursionExamplePassesAllValidation, validationResults);
151+
return isValid && validationResults.Any() == false;
152+
}
153+
154+
#endregion
155+
156+
#region SimpleExample
157+
158+
private static readonly SimpleExample SimpleExamplePassesAllValidation = new SimpleExample
159+
{
160+
IntegerA = 100,
161+
StringB = "test-100",
162+
BoolC = true,
163+
ExampleEnumD = ExampleEnum.ValueB
164+
};
165+
166+
[Benchmark]
167+
public bool SimpleExample_PassesAllValidation()
168+
{
169+
var validationResults = new List<ValidationResult>();
170+
var isValid = _sut.TryValidateObjectRecursive(SimpleExamplePassesAllValidation, validationResults);
171+
return isValid && validationResults.Any() == false;
172+
}
173+
174+
private static readonly SimpleExample SimpleExampleAllNull = new SimpleExample
175+
{
176+
IntegerA = null,
177+
StringB = null,
178+
BoolC = null,
179+
ExampleEnumD = null
180+
};
181+
182+
[Benchmark]
183+
public bool SimpleExample_AllNull()
184+
{
185+
var validationResults = new List<ValidationResult>();
186+
var isValid = _sut.TryValidateObjectRecursive(SimpleExampleAllNull, validationResults);
187+
return isValid && validationResults.Any() == false;
188+
}
189+
190+
#endregion
191+
192+
#region SkippedChildrenExample
193+
194+
private static readonly SkippedChildrenExample SkippedChildrenExamplePassesAllValidation =
195+
new SkippedChildrenExample
196+
{
197+
Name = "some name for pass all",
198+
SimpleA = new SimpleExample
199+
{
200+
StringB = "simple A pass-all",
201+
BoolC = false,
202+
IntegerA = 125,
203+
ExampleEnumD = ExampleEnum.ValueB,
204+
},
205+
SimpleB = new SimpleExample
206+
{
207+
StringB = "simple B pass-all",
208+
BoolC = true,
209+
IntegerA = 95,
210+
ExampleEnumD = ExampleEnum.ValueA,
211+
},
212+
};
213+
214+
[Benchmark]
215+
public bool SkippedChildrenExample_PassesAllValidation()
216+
{
217+
var validationResults = new List<ValidationResult>();
218+
var isValid = _sut.TryValidateObjectRecursive(SkippedChildrenExamplePassesAllValidation, validationResults);
219+
return isValid && validationResults.Any() == false;
220+
}
221+
222+
private static readonly SkippedChildrenExample SkippedChildrenExampleAllNull = new SkippedChildrenExample
223+
{
224+
Name = null,
225+
SimpleA = new SimpleExample
226+
{
227+
StringB = null,
228+
BoolC = null,
229+
IntegerA = null,
230+
ExampleEnumD = null,
231+
},
232+
SimpleB = null,
233+
};
234+
235+
[Benchmark]
236+
public bool SkippedChildrenExample_AllNull()
237+
{
238+
var validationResults = new List<ValidationResult>();
239+
var isValid = _sut.TryValidateObjectRecursive(SkippedChildrenExampleAllNull, validationResults);
240+
return isValid && validationResults.Any() == false;
241+
}
242+
243+
#endregion
244+
}
245+
}

benchmark/Benchmark/Program.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using BenchmarkDotNet.Running;
2+
3+
namespace Benchmark
4+
{
5+
public class Program
6+
{
7+
public static void Main(string[] args)
8+
{
9+
// https://benchmarkdotnet.org/articles/guides/console-args.html
10+
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
11+
}
12+
}
13+
}

benchmark/Benchmark/run.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/usr/bin/env sh
2+
# Run this from the root of the solution, not the benchmark directory.
3+
# See: https://benchmarkdotnet.org/articles/guides/console-args.html
4+
dotnet build --configuration Release && \
5+
dotnet run --configuration Release --project benchmark/Benchmark -- --filter '*' --memory
6+

0 commit comments

Comments
 (0)