Skip to content

Commit 6b27f81

Browse files
committed
* PerfTests: AggressiveInliningPerfTests
* RangesV2: perftests run on x64
1 parent 3f81406 commit 6b27f81

File tree

5 files changed

+272
-3
lines changed

5 files changed

+272
-3
lines changed

Experimental/src/RangesV2/[Boundaries]/RangeBoundaryFrom`1.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ public partial struct RangeBoundaryFrom<T> :
4646

4747
private static readonly bool _hasPositiveInfinity = Operators<T>.HasPositiveInfinity;
4848

49-
/// <summary>The _positive infinity</summary>
5049
private static readonly T _positiveInfinity = Operators<T>.HasPositiveInfinity
5150
? Operators<T>.PositiveInfinity
5251
: default(T);

Experimental/src/RangesV2/[Boundaries]/RangeBoundaryTo`1.generated.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ public partial struct RangeBoundaryTo<T> :
5555

5656
private static readonly bool _hasNegativeInfinity = Operators<T>.HasNegativeInfinity;
5757

58-
/// <summary>The _negative infinity</summary>
5958
private static readonly T _negativeInfinity = Operators<T>.HasNegativeInfinity
6059
? Operators<T>.NegativeInfinity
6160
: default(T);

Experimental/tests-performance/RangesV2/RangeBoundaryFactoryPerfTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public RangeBoundaryFrom<int> Test00Validated()
3333
return result;
3434
}
3535

36-
[CompetitionBenchmark(0.46, 0.50)]
36+
[CompetitionBenchmark(0.83, 0.90)]
3737
public RangeBoundaryFrom<int> Test01NoValidation()
3838
{
3939
var result = RangeBoundaryFrom<int>.Empty;
Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
using System;
2+
using System.Runtime.CompilerServices;
3+
4+
using BenchmarkDotNet.UnitTesting;
5+
6+
using CodeJam.Arithmetic;
7+
8+
using NUnit.Framework;
9+
10+
using static CodeJam.AssemblyWideConfig;
11+
12+
namespace CodeJam
13+
{
14+
/// <summary>
15+
/// Proof test: Aggressive inlining can be used to boost the code.
16+
/// </summary>
17+
[TestFixture(Category = PerfTestsConstants.PerfTestCategory + ": Self-testing")]
18+
[Explicit(PerfTestsConstants.ExplicitExcludeReason)]
19+
public class AggressiveInliningPerfTests
20+
{
21+
// Use case:
22+
// 1. We have a complex logec split into multiple methods
23+
// 2. The logic is used on hotpath
24+
// 3. [MethodImpl(AggressiveInlining)] can be used to force the inlining and to speedup the code.
25+
// NB: use with care. In some cases inlining can result in significant slowdown.
26+
private const int Count = 10 * 1000 * 1000;
27+
28+
[Test]
29+
public void RunCaseAggInlineNoEffect() =>
30+
CompetitionBenchmarkRunner.Run<CaseAggInlineNoEffect>(RunConfig);
31+
32+
public class CaseAggInlineNoEffect
33+
{
34+
#region PerfTest helpers
35+
private static int CallManualInline(int i) => i + 5;
36+
37+
// Will inline - auto
38+
private static int CallAuto1(int i) => CallAuto2(i) + 1;
39+
private static int CallAuto2(int i) => CallAuto3(i) + 1;
40+
private static int CallAuto3(int i) => CallAuto4(i) + 1;
41+
private static int CallAuto4(int i) => CallAuto5(i) + 1;
42+
private static int CallAuto5(int i) => i + 1;
43+
44+
// Will NOT inline - forced
45+
[MethodImpl(MethodImplOptions.NoInlining)]
46+
private static int CallNoInline1(int i) => CallNoInline2(i) + 1;
47+
48+
[MethodImpl(MethodImplOptions.NoInlining)]
49+
private static int CallNoInline2(int i) => CallNoInline3(i) + 1;
50+
51+
[MethodImpl(MethodImplOptions.NoInlining)]
52+
private static int CallNoInline3(int i) => CallNoInline4(i) + 1;
53+
54+
[MethodImpl(MethodImplOptions.NoInlining)]
55+
private static int CallNoInline4(int i) => CallNoInline5(i) + 1;
56+
57+
[MethodImpl(MethodImplOptions.NoInlining)]
58+
private static int CallNoInline5(int i) => i + 1;
59+
60+
// Will inline - forced
61+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
62+
private static int CallInline1(int i) => CallInline2(i) + 1;
63+
64+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
65+
private static int CallInline2(int i) => CallInline3(i) + 1;
66+
67+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
68+
private static int CallInline3(int i) => CallInline4(i) + 1;
69+
70+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
71+
private static int CallInline4(int i) => CallInline5(i) + 1;
72+
73+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
74+
private static int CallInline5(int i) => i + 1;
75+
#endregion
76+
77+
[CompetitionBaseline]
78+
public int Test00Baseline()
79+
{
80+
var sum = 0;
81+
for (var i = 0; i < Count; i++)
82+
{
83+
sum += CallManualInline(i);
84+
}
85+
return sum;
86+
}
87+
88+
[CompetitionBenchmark(0.97, 1.04)]
89+
public int Test01Auto()
90+
{
91+
var sum = 0;
92+
for (var i = 0; i < Count; i++)
93+
{
94+
sum += CallAuto1(i);
95+
}
96+
return sum;
97+
}
98+
99+
[CompetitionBenchmark(10.33, 11.01)]
100+
public int Test02NoInline()
101+
{
102+
var sum = 0;
103+
for (var i = 0; i < Count; i++)
104+
{
105+
sum += CallNoInline1(i);
106+
}
107+
return sum;
108+
}
109+
110+
111+
[CompetitionBenchmark(0.96, 1.04)]
112+
public int Test03AggressiveInline()
113+
{
114+
var sum = 0;
115+
for (var i = 0; i < Count; i++)
116+
{
117+
sum += CallInline1(i);
118+
}
119+
return sum;
120+
}
121+
}
122+
123+
[Test]
124+
public void RunCaseAggInlineEffective() =>
125+
CompetitionBenchmarkRunner.Run<CaseAggInlineEffective>(RunConfig);
126+
127+
public class CaseAggInlineEffective
128+
{
129+
#region PerfTest helpers
130+
// Will NOT inline - auto
131+
private struct StructAuto<T>
132+
{
133+
private static readonly Func<T, T, int> _compareFunc = Operators<T>.Compare;
134+
135+
public StructAuto(T value, bool validate)
136+
{
137+
if (validate)
138+
{
139+
if (_compareFunc(value, default(T)) != 0)
140+
{
141+
throw new Exception("1");
142+
}
143+
}
144+
else
145+
{
146+
if (value == null)
147+
{
148+
throw new Exception("2");
149+
}
150+
}
151+
Value = value;
152+
}
153+
154+
public T Value { get; }
155+
}
156+
157+
// Will NOT inline - forced
158+
private struct StructNoInline<T>
159+
{
160+
private static readonly Func<T, T, int> _compareFunc = Operators<T>.Compare;
161+
162+
public StructNoInline(T value, bool validate)
163+
{
164+
if (validate)
165+
{
166+
if (_compareFunc(value, default(T)) != 0)
167+
{
168+
throw new Exception("1");
169+
}
170+
}
171+
else
172+
{
173+
if (value == null)
174+
{
175+
throw new Exception("2");
176+
}
177+
}
178+
Value = value;
179+
}
180+
181+
public T Value { get; }
182+
}
183+
184+
// Will inline - forced
185+
private struct StructInline<T>
186+
{
187+
private static readonly Func<T, T, int> _compareFunc = Operators<T>.Compare;
188+
189+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
190+
public StructInline(T value, bool validate)
191+
{
192+
if (validate)
193+
{
194+
if (_compareFunc(value, default(T)) != 0)
195+
{
196+
throw new Exception("1");
197+
}
198+
}
199+
else
200+
{
201+
if (value == null)
202+
{
203+
throw new Exception("2");
204+
}
205+
}
206+
Value = value;
207+
}
208+
209+
public T Value { get; }
210+
}
211+
212+
private static int CallManualInline(int i) => i + 1;
213+
214+
private static int CallAuto(int i) =>
215+
new StructAuto<int>(i, false).Value + 1;
216+
217+
private static int CallNoInline(int i) =>
218+
new StructNoInline<int>(i, false).Value + 1;
219+
220+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
221+
private static int CallInline(int i) =>
222+
new StructInline<int>(i, false).Value + 1;
223+
#endregion
224+
225+
[CompetitionBaseline]
226+
public int Test00Baseline()
227+
{
228+
var sum = 0;
229+
for (var i = 0; i < Count; i++)
230+
{
231+
sum += CallManualInline(i);
232+
}
233+
return sum;
234+
}
235+
236+
[CompetitionBenchmark(5.82, 6.20)]
237+
public int Test01Auto()
238+
{
239+
var sum = 0;
240+
for (var i = 0; i < Count; i++)
241+
{
242+
sum += CallAuto(i);
243+
}
244+
return sum;
245+
}
246+
247+
[CompetitionBenchmark(5.74, 6.12)]
248+
public int Test02NoInline()
249+
{
250+
var sum = 0;
251+
for (var i = 0; i < Count; i++)
252+
{
253+
sum += CallNoInline(i);
254+
}
255+
return sum;
256+
}
257+
258+
[CompetitionBenchmark(0.98, 1.05)]
259+
public int Test03AggressiveInline()
260+
{
261+
var sum = 0;
262+
for (var i = 0; i < Count; i++)
263+
{
264+
sum += CallInline(i);
265+
}
266+
return sum;
267+
}
268+
}
269+
}
270+
}

Main/tests-performance/CodeJam.Main-Tests.Performance.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
<Compile Include="BenchmarkDotNet\UnitTesting\CompetitionParameters.cs" />
104104
<Compile Include="BenchmarkDotNet\UnitTesting\CompetitionState.cs" />
105105
<Compile Include="BenchmarkDotNet\UnitTesting\Configs.cs" />
106+
<Compile Include="CalibrationBenchmarks\AggressiveInliningPerfTests.cs" />
106107
<Compile Include="CalibrationBenchmarks\JitOptimizedFeatureSwitchPerfTests.cs" />
107108
<Compile Include="PerfTestsConstants.cs" />
108109
<Compile Include="CalibrationBenchmarks\NestedStructAccessPerfTests.cs" />

0 commit comments

Comments
 (0)