diff --git a/src/benchmarks/micro/coreclr/Devirtualization/GuardedThreeClassInterface.cs b/src/benchmarks/micro/coreclr/Devirtualization/GuardedThreeClassInterface.cs index a7363587ebc..7a873fa867d 100644 --- a/src/benchmarks/micro/coreclr/Devirtualization/GuardedThreeClassInterface.cs +++ b/src/benchmarks/micro/coreclr/Devirtualization/GuardedThreeClassInterface.cs @@ -2,121 +2,95 @@ // 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; using System.Collections.Generic; +using System.Linq; using BenchmarkDotNet.Attributes; using MicroBenchmarks; // Performance test for virtual call dispatch with three // possible target classes mixed in varying proportions. -// -// Note: for now we type the test input as B[] and not I[] -// so the simple guessing heuristic in the jit has a class -// to guess for. -namespace GuardedDevirtualizationThreeClassInterface -{ - -interface I -{ - int F(); -} - -public class B : I -{ - int I.F() => 33; -} - -public class D : B, I -{ - int I.F() => 44; -} - -public class E : B, I -{ - int I.F() => 55; -} - -public class TestInput -{ - public const int N = 1000; - - public TestInput(double pB, double pD) - { - _pB = pB; - _pD = pD; - b = GetArray(); - } - - static Random r = new Random(42); - - double _pB; - double _pD; - B[] b; - - public B[] Array => b; - public override string ToString() => $"pB={_pB:F2} pD={_pD:F2}"; - - B[] GetArray() +namespace GuardedDevirtualization +{ + [BenchmarkCategory(Categories.CoreCLR, Categories.Virtual)] + public class ThreeClassInterface { - B[] result = new B[N]; - - for (int i = 0; i < N; i++) + interface I { - double p = r.NextDouble(); - - if (p <= _pB) - { - result[i] = new B(); - } - else if (p <= _pB + _pD) - { - result[i] = new D(); - } - else + int F(); + } + + public class B : I + { + int I.F() => 33; + } + + public class D : B, I + { + int I.F() => 44; + } + + public class E : B, I + { + int I.F() => 55; + } + + [Benchmark(OperationsPerInvoke=TestInput.N)] + [ArgumentsSource(nameof(GetInput))] + public long Call(TestInput testInput) + { + long sum = 0; + + // Note: for now we type the test input as B[] and not I[] + // so the simple guessing heuristic in the jit has a class + // to guess for. + B[] input = testInput.Array; + for (int i = 0; i < input.Length; i++) { - result[i] = new E(); + sum += ((I)input[i]).F(); } + return sum; } - return result; - } -} - -[BenchmarkCategory(Categories.CoreCLR, Categories.Virtual)] -public class Interface -{ - [Benchmark(OperationsPerInvoke=TestInput.N)] - [ArgumentsSource(nameof(GetInput))] - public long Call3(TestInput testInput) - { - long sum = 0; - B[] input = testInput.Array; - for (int i = 0; i < input.Length; i++) + + public static IEnumerable GetInput() { - sum += ((I)input[i]).F(); + 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); + } + } } - return sum; - } - - static int S = 3; - static double delta = 1.0 / (double) S; - - public static IEnumerable GetInput() - { - double pB = 0; - - for (int i = 0; i <= S; i++, pB += delta) + + public class TestInput { - double pD = 0; + public const int N = 1000; - for (int j = 0; j <= S - i; j++, pD += delta) + public B[] Array; + private double _pB; + private double _pD; + + public TestInput(double pB, double pD) { - yield return new TestInput(pB, pD); + _pB = pB; + _pD = pD; + Array = ValuesGenerator.Array(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}"; } } } -} - diff --git a/src/benchmarks/micro/coreclr/Devirtualization/GuardedThreeClassVirtual.cs b/src/benchmarks/micro/coreclr/Devirtualization/GuardedThreeClassVirtual.cs index dbd7ee37e60..77a08ee331d 100644 --- a/src/benchmarks/micro/coreclr/Devirtualization/GuardedThreeClassVirtual.cs +++ b/src/benchmarks/micro/coreclr/Devirtualization/GuardedThreeClassVirtual.cs @@ -2,112 +2,86 @@ // 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; using System.Collections.Generic; +using System.Linq; using BenchmarkDotNet.Attributes; using MicroBenchmarks; // Performance test for virtual call dispatch with three // possible target classes mixed in varying proportions. -namespace GuardedDevirtualizationThreeClass -{ - -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; -} - -public class TestInput -{ - public const int N = 1000; - - public TestInput(double pB, double pD) - { - _pB = pB; - _pD = pD; - b = GetArray(); - } - - static Random r = new Random(42); - - double _pB; - double _pD; - B[] b; - - public B[] Array => b; - public override string ToString() => $"pB={_pB:F2} pD={_pD:F2}"; - - B[] GetArray() +namespace GuardedDevirtualization +{ + [BenchmarkCategory(Categories.CoreCLR, Categories.Virtual)] + public class ThreeClassVirtual { - B[] result = new B[N]; - - for (int i = 0; i < N; i++) + public class B { - double p = r.NextDouble(); - - if (p <= _pB) - { - result[i] = new B(); - } - else if (p <= _pB + _pD) - { - result[i] = new D(); - } - else + 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++) { - result[i] = new E(); + sum += input[i].F(); } + return sum; } - return result; - } -} - -[BenchmarkCategory(Categories.CoreCLR, Categories.Virtual)] -public class Virtual -{ - [Benchmark(OperationsPerInvoke=TestInput.N)] - [ArgumentsSource(nameof(GetInput))] - public long Call3(TestInput testInput) - { - long sum = 0; - B[] input = testInput.Array; - for (int i = 0; i < input.Length; i++) + + public static IEnumerable GetInput() { - sum += input[i].F(); + 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); + } + } } - return sum; - } - - static int S = 3; - static double delta = 1.0 / (double) S; - - public static IEnumerable GetInput() - { - double pB = 0; - - for (int i = 0; i <= S; i++, pB += delta) + + public class TestInput { - double pD = 0; + public const int N = 1000; - for (int j = 0; j <= S - i; j++, pD += delta) + public B[] Array; + private double _pB; + private double _pD; + + public TestInput(double pB, double pD) { - yield return new TestInput(pB, pD); + _pB = pB; + _pD = pD; + Array = ValuesGenerator.Array(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}"; + } } } -} - diff --git a/src/benchmarks/micro/coreclr/Devirtualization/GuardedTwoClassInterface.cs b/src/benchmarks/micro/coreclr/Devirtualization/GuardedTwoClassInterface.cs index 3dacdd0fd1b..91299a9313d 100644 --- a/src/benchmarks/micro/coreclr/Devirtualization/GuardedTwoClassInterface.cs +++ b/src/benchmarks/micro/coreclr/Devirtualization/GuardedTwoClassInterface.cs @@ -2,104 +2,76 @@ // 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; using System.Collections.Generic; +using System.Linq; using BenchmarkDotNet.Attributes; using MicroBenchmarks; // Performance test for interface call dispatch with two // possible target classes mixed in varying proportions. -// -// Note: for now we type the test input as B[] and not I[] -// so the simple guessing heuristic in the jit has a class -// to guess for. -namespace GuardedDevirtualizationTwoClassInterface +namespace GuardedDevirtualization { - -interface I -{ - int F(); -} - -public class B : I -{ - int I.F() => 33; -} - -public class D : B, I -{ - int I.F() => 44; -} - -public class TestInput -{ - public const int N = 1000; - - public TestInput(double pB) + [BenchmarkCategory(Categories.CoreCLR, Categories.Virtual)] + public class TwoClassInterface { - _pB = pB; - b = GetArray(); - } - - static Random r = new Random(42); + interface I + { + int F(); + } - double _pB; - B[] b; + public class B : I + { + int I.F() => 33; + } - public B[] Array => b; - public override string ToString() => $"pB = {_pB:F2}"; + public class D : B, I + { + int I.F() => 44; + } - B[] GetArray() - { - B[] result = new B[N]; - for (int i = 0; i < N; i++) + [Benchmark(OperationsPerInvoke = TestInput.N)] + [ArgumentsSource(nameof(GetInput))] + public long Call(TestInput testInput) { - double p = r.NextDouble(); - if (p > _pB) + long sum = 0; + + // Note: for now we type the test input as B[] and not I[] + // so the simple guessing heuristic in the jit has a class + // to guess for. + B[] input = testInput.Array; + for (int i = 0; i < input.Length; i++) { - result[i] = new D(); + sum += ((I)input[i]).F(); } - else + + return sum; + } + + public static IEnumerable GetInput() + { + for (double pB = 0; pB <= 1.0; pB += 0.1) { - result[i] = new B(); + yield return new TestInput(pB); } } - return result; - } -} -[BenchmarkCategory(Categories.CoreCLR, Categories.Virtual)] -public class Interface -{ - [Benchmark(OperationsPerInvoke=TestInput.N)] - [ArgumentsSource(nameof(GetInput))] - public long Call2(TestInput testInput) - { - long sum = 0; - - B[] input = testInput.Array; - for (int i = 0; i < input.Length; i++) + public class TestInput { - sum += ((I)input[i]).F(); - } - return sum; - } + public const int N = 1000; - static int S = 10; - static double delta = 1.0 / (double) S; + public B[] Array; + private double _pB; - public static IEnumerable GetInput() - { - double pB = 0; + public TestInput(double pB) + { + _pB = pB; + Array = ValuesGenerator.Array(N).Select(p => p > _pB ? new D() : new B()).ToArray(); + } - for (int i = 0; i <= S; i++, pB += delta) - { - yield return new TestInput(pB); + public override string ToString() => $"pB = {_pB:F2}"; } } } -} - diff --git a/src/benchmarks/micro/coreclr/Devirtualization/GuardedTwoClassVirtual.cs b/src/benchmarks/micro/coreclr/Devirtualization/GuardedTwoClassVirtual.cs index e0962981faa..976b2cd4602 100644 --- a/src/benchmarks/micro/coreclr/Devirtualization/GuardedTwoClassVirtual.cs +++ b/src/benchmarks/micro/coreclr/Devirtualization/GuardedTwoClassVirtual.cs @@ -2,94 +2,65 @@ // 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; using System.Collections.Generic; +using System.Linq; using BenchmarkDotNet.Attributes; using MicroBenchmarks; // Performance test for virtual call dispatch with two // possible target classes mixed in varying proportions. -namespace GuardedDevirtualizationTwoClass +namespace GuardedDevirtualization { - -public class B -{ - public virtual int F() => 33; -} - -public class D : B -{ - public override int F() => 44; -} - -public class TestInput -{ - public const int N = 1000; - - public TestInput(double pB) + [BenchmarkCategory(Categories.CoreCLR, Categories.Virtual)] + public class TwoClassVirtual { - _pB = pB; - b = GetArray(); - } - - static Random r = new Random(42); - - double _pB; - B[] b; + public class B + { + public virtual int F() => 33; + } - public B[] Array => b; - public override string ToString() => $"pB = {_pB:F2}"; + public class D : B + { + public override int F() => 44; + } - B[] GetArray() - { - B[] result = new B[N]; - for (int i = 0; i < N; i++) + [Benchmark(OperationsPerInvoke = TestInput.N)] + [ArgumentsSource(nameof(GetInput))] + public long Call(TestInput testInput) { - double p = r.NextDouble(); - if (p > _pB) - { - result[i] = new D(); - } - else + long sum = 0; + B[] input = testInput.Array; + for (int i = 0; i < input.Length; i++) { - result[i] = new B(); + sum += input[i].F(); } + + return sum; } - return result; - } -} -[BenchmarkCategory(Categories.CoreCLR, Categories.Virtual)] -public class Virtual -{ - [Benchmark(OperationsPerInvoke=TestInput.N)] - [ArgumentsSource(nameof(GetInput))] - public long Call2(TestInput testInput) - { - long sum = 0; - B[] input = testInput.Array; - for (int i = 0; i < input.Length; i++) + public static IEnumerable GetInput() { - sum += input[i].F(); + for (double pB = 0; pB <= 1.0; pB += 0.1) + { + yield return new TestInput(pB); + } } - return sum; - } - static int S = 10; - static double delta = 1.0 / (double) S; + public class TestInput + { + public const int N = 1000; + + public B[] Array; + private double _pB; - public static IEnumerable GetInput() - { - double pB = 0; + public TestInput(double pB) + { + _pB = pB; + Array = ValuesGenerator.Array(N).Select(p => p > _pB ? new D() : new B()).ToArray(); + } - for (int i = 0; i <= S; i++, pB += delta) - { - yield return new TestInput(pB); + public override string ToString() => $"pB = {_pB:F2}"; } } -} - -} - - +} \ No newline at end of file