-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathBenchmarkBase.cs
68 lines (58 loc) · 1.79 KB
/
BenchmarkBase.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
namespace Open.Diagnostics;
public abstract class BenchmarkBase<TBenchParam>
{
public readonly uint TestSize;
public readonly uint RepeatCount; // Number of times to repeat the test from scratch.
protected readonly TBenchParam Param;
protected BenchmarkBase(uint size, uint repeat, TBenchParam param)
{
TestSize = size;
RepeatCount = repeat;
Param = param;
}
public IEnumerable<(int Index, TimedResult Result)> TestOnce()
{
var index = 0;
var total = TimeSpan.Zero;
foreach (var r in TestOnceInternal())
{
total += r.Duration;
yield return (index++, r);
}
yield return (index, new TimedResult("TOTAL", total));
}
protected abstract IEnumerable<TimedResult> TestOnceInternal();
public IEnumerable<IEnumerable<(int Index, TimedResult Result)>> TestRepeated()
{
for (var i = 0; i < RepeatCount; i++)
{
yield return TestOnce();
}
}
TimedResult[]? _result;
public TimedResult[] Result
=> LazyInitializer.EnsureInitialized(
ref _result, () =>
TestRepeated()
.SelectMany(s => s) // Get all results.
.GroupBy(k => k.Index) // Group by their 'id' (ordinal).
.Select(Sum) // Sum/merge those groups.
.OrderBy(r => r.Index) // Order by their ordinal.
.Select(r => r.Result) // Select the actual result.
.ToArray() // And done.
)!;
static (int Index, TimedResult Result) Sum(IEnumerable<(int Index, TimedResult Result)> results)
{
var a = results.ToArray();
if (a.Length == 0) return (-1, default);
var i = a[0].Index;
return a.Skip(1).Any(r => r.Index != i)
? throw new InvalidOperationException("Summing unmatched TimeResults.")
: ((int Index, TimedResult Result))(i, a.Select(s => s.Result).Sum());
}
}