-
Notifications
You must be signed in to change notification settings - Fork 272
/
GuardedThreeClassVirtual.cs
88 lines (74 loc) · 2.35 KB
/
GuardedThreeClassVirtual.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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Linq;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Extensions;
using MicroBenchmarks;
// Performance test for virtual call dispatch with three
// possible target classes mixed in varying proportions.
namespace GuardedDevirtualization
{
[BenchmarkCategory(Categories.Runtime, Categories.Virtual)]
public class ThreeClassVirtual
{
public class B
{
public virtual int F() => 33;
}
public class D : B
{
public override int F() => 44;
}
public class E : B
{
public override int F() => 55;
}
[Benchmark(OperationsPerInvoke=TestInput.N)]
[ArgumentsSource(nameof(GetInput))]
public long Call(TestInput testInput)
{
long sum = 0;
B[] input = testInput.Array;
for (int i = 0; i < input.Length; i++)
{
sum += input[i].F();
}
return sum;
}
public static IEnumerable<TestInput> GetInput()
{
const int S = 3;
const double delta = 1.0 / (double) S;
for (int i = 0; i <= S; i++)
{
for (int j = 0; j <= S - i; j++)
{
yield return new TestInput(i * delta, j * delta);
}
}
}
public class TestInput
{
public const int N = 1000;
public B[] Array;
private double _pB;
private double _pD;
public TestInput(double pB, double pD)
{
_pB = pB;
_pD = pD;
Array = ValuesGenerator.Array<double>(N).Select(p =>
{
if (p <= _pB)
return new B();
if (p <= _pB + _pD)
return new D();
return new E();
}).ToArray();
}
public override string ToString() => $"pB={_pB:F2} pD={_pD:F2}";
}
}
}