[benchmarks] Add benchmark for taking tear-offs repeatedly

Issue: https://github.com/dart-lang/sdk/issues/54808
Change-Id: Ice28033bab71e30f9a586564d7e55d9c4f5ce770
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/350640
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
Alexander Markov 2024-02-07 15:16:19 +00:00 committed by Commit Queue
parent 6ee8a42a79
commit e7eb0aaa20

View file

@ -0,0 +1,192 @@
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:benchmark_harness/benchmark_harness.dart';
// Micro-benchmark for taking tear-off of instance method multiple
// times and in a loop.
class BenchTearOffInlined extends BenchmarkBase {
BenchTearOffInlined() : super('TearOff.Inlined');
int sum = 0;
@pragma('vm:prefer-inline')
@pragma('dart2js:prefer-inline')
void foo(int arg) {
sum += arg;
}
@pragma('vm:prefer-inline')
@pragma('dart2js:prefer-inline')
void callIt(void Function(int) func, int arg) {
func(arg);
}
@override
@pragma('vm:never-inline')
@pragma('dart2js:never-inline')
void run() {
sum = 0;
callIt(foo, 1);
callIt(foo, 2);
callIt(foo, 3);
callIt(foo, 4);
callIt(foo, 5);
for (int i = 11; i < 20; ++i) {
callIt(foo, i);
}
callIt(foo, 6);
callIt(foo, 7);
callIt(foo, 8);
callIt(foo, 9);
callIt(foo, 10);
const int expectedSum = 20 * (20 - 1) ~/ 2;
if (sum != expectedSum) throw 'Bad result: $sum';
}
}
class BenchTearOffInlinedInTry extends BenchmarkBase {
BenchTearOffInlinedInTry() : super('TearOff.Inlined.InTry');
int sum = 0;
@pragma('vm:prefer-inline')
@pragma('dart2js:prefer-inline')
void foo(int arg) {
sum += arg;
}
@pragma('vm:prefer-inline')
@pragma('dart2js:prefer-inline')
void callIt(void Function(int) func, int arg) {
func(arg);
}
@override
@pragma('vm:never-inline')
@pragma('dart2js:never-inline')
void run() {
sum = 0;
try {
callIt(foo, 1);
callIt(foo, 2);
callIt(foo, 3);
callIt(foo, 4);
callIt(foo, 5);
for (int i = 11; i < 20; ++i) {
callIt(foo, i);
}
callIt(foo, 6);
callIt(foo, 7);
callIt(foo, 8);
callIt(foo, 9);
callIt(foo, 10);
} finally {
const int expectedSum = 20 * (20 - 1) ~/ 2;
if (sum != expectedSum) throw 'Bad result: $sum';
}
}
}
class BenchTearOffNotInlined extends BenchmarkBase {
BenchTearOffNotInlined() : super('TearOff.NotInlined');
int sum = 0;
@pragma('vm:never-inline')
@pragma('dart2js:never-inline')
void foo(int arg) {
sum += arg;
}
@pragma('vm:never-inline')
@pragma('dart2js:never-inline')
void callIt(void Function(int) func, int arg) {
func(arg);
}
@override
@pragma('vm:never-inline')
@pragma('dart2js:never-inline')
void run() {
sum = 0;
callIt(foo, 1);
callIt(foo, 2);
callIt(foo, 3);
callIt(foo, 4);
callIt(foo, 5);
for (int i = 11; i < 20; ++i) {
callIt(foo, i);
}
callIt(foo, 6);
callIt(foo, 7);
callIt(foo, 8);
callIt(foo, 9);
callIt(foo, 10);
const int expectedSum = 20 * (20 - 1) ~/ 2;
if (sum != expectedSum) throw 'Bad result: $sum';
}
}
class BenchTearOffNotInlinedInTry extends BenchmarkBase {
BenchTearOffNotInlinedInTry() : super('TearOff.NotInlined.InTry');
int sum = 0;
@pragma('vm:never-inline')
@pragma('dart2js:never-inline')
void foo(int arg) {
sum += arg;
}
@pragma('vm:never-inline')
@pragma('dart2js:never-inline')
void callIt(void Function(int) func, int arg) {
func(arg);
}
@override
@pragma('vm:never-inline')
@pragma('dart2js:never-inline')
void run() {
sum = 0;
try {
callIt(foo, 1);
callIt(foo, 2);
callIt(foo, 3);
callIt(foo, 4);
callIt(foo, 5);
for (int i = 11; i < 20; ++i) {
callIt(foo, i);
}
callIt(foo, 6);
callIt(foo, 7);
callIt(foo, 8);
callIt(foo, 9);
callIt(foo, 10);
} finally {
const int expectedSum = 20 * (20 - 1) ~/ 2;
if (sum != expectedSum) throw 'Bad result: $sum';
}
}
}
void main() {
final benchmarks = [
BenchTearOffInlined(),
BenchTearOffInlinedInTry(),
BenchTearOffNotInlined(),
BenchTearOffNotInlinedInTry(),
];
for (final benchmark in benchmarks) {
benchmark.warmup();
}
for (final benchmark in benchmarks) {
benchmark.report();
}
}