mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 12:24:24 +00:00
b0bfee6627
The implementation of const map literals is based on linear lookups in an array containing key/value pairs instead of a hash table. Bug: https://github.com/dart-lang/sdk/issues/45908 Golem CL: https://chrome-internal-review.googlesource.com/c/golem/+/3852562 Change-Id: If0a980339ee1342c41f9388e0bd7b3615a4ef4e3 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/200188 Commit-Queue: Daco Harkes <dacoharkes@google.com> Reviewed-by: Jonas Termansen <sortie@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com>
863 lines
22 KiB
Dart
863 lines
22 KiB
Dart
// Copyright (c) 2019, 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.
|
|
|
|
// Micro-benchmarks for sync/sync*/async/async* functionality.
|
|
|
|
import 'dart:async';
|
|
|
|
const int iterationLimitAsync = 200;
|
|
const int sumOfIterationLimitAsync =
|
|
iterationLimitAsync * (iterationLimitAsync - 1) ~/ 2;
|
|
|
|
const int iterationLimitSync = 5000;
|
|
const int sumOfIterationLimitSync =
|
|
iterationLimitSync * (iterationLimitSync - 1) ~/ 2;
|
|
|
|
Future main() async {
|
|
final target = Target();
|
|
final target2 = Target2();
|
|
final target3 = Target3();
|
|
|
|
// Ensure the call sites will have another target in the ICData.
|
|
await performAwaitCallsClosureTargetPolymorphic(returnAsync);
|
|
await performAwaitCallsClosureTargetPolymorphic(returnFuture);
|
|
await performAwaitCallsClosureTargetPolymorphic(returnFutureOr);
|
|
await performAwaitAsyncCallsInstanceTargetPolymorphic(target);
|
|
await performAwaitAsyncCallsInstanceTargetPolymorphic(target2);
|
|
await performAwaitAsyncCallsInstanceTargetPolymorphic(target3);
|
|
await performAwaitFutureCallsInstanceTargetPolymorphic(target);
|
|
await performAwaitFutureCallsInstanceTargetPolymorphic(target2);
|
|
await performAwaitFutureCallsInstanceTargetPolymorphic(target3);
|
|
await performAwaitFutureOrCallsInstanceTargetPolymorphic(target);
|
|
await performAwaitFutureOrCallsInstanceTargetPolymorphic(target2);
|
|
await performAwaitFutureOrCallsInstanceTargetPolymorphic(target3);
|
|
performSyncCallsInstanceTargetPolymorphic(target);
|
|
performSyncCallsInstanceTargetPolymorphic(target2);
|
|
performSyncCallsInstanceTargetPolymorphic(target3);
|
|
await performAwaitAsyncCallsInstanceTargetPolymorphicManyAwaits(target);
|
|
await performAwaitAsyncCallsInstanceTargetPolymorphicManyAwaits(target2);
|
|
await performAwaitAsyncCallsInstanceTargetPolymorphicManyAwaits(target3);
|
|
|
|
await performAwaitForIterationPolymorphic(generateNumbersAsyncStar);
|
|
await performAwaitForIterationPolymorphic(generateNumbersAsyncStar2);
|
|
await performAwaitForIterationPolymorphic(generateNumbersManualAsync);
|
|
await performAwaitForIterationPolymorphic(generateNumbersAsyncStarManyYields);
|
|
performSyncIterationPolymorphic(generateNumbersSyncStar);
|
|
performSyncIterationPolymorphic(generateNumbersSyncStar2);
|
|
performSyncIterationPolymorphic(generateNumbersManual);
|
|
performSyncIterationPolymorphic(generateNumbersSyncStarManyYields);
|
|
|
|
await AsyncCallBenchmark('Calls.AwaitAsyncCall', performAwaitAsyncCalls)
|
|
.report();
|
|
await AsyncCallBenchmark('Calls.AwaitAsyncCallClosureTargetPolymorphic',
|
|
() => performAwaitCallsClosureTargetPolymorphic(returnAsync)).report();
|
|
await AsyncCallBenchmark('Calls.AwaitAsyncCallInstanceTargetPolymorphic',
|
|
() => performAwaitAsyncCallsInstanceTargetPolymorphic(target)).report();
|
|
|
|
await AsyncCallBenchmark('Calls.AwaitFutureCall', performAwaitFutureCalls)
|
|
.report();
|
|
await AsyncCallBenchmark('Calls.AwaitFutureCallClosureTargetPolymorphic',
|
|
() => performAwaitCallsClosureTargetPolymorphic(returnFuture)).report();
|
|
await AsyncCallBenchmark('Calls.AwaitFutureCallInstanceTargetPolymorphic',
|
|
() => performAwaitFutureCallsInstanceTargetPolymorphic(target)).report();
|
|
|
|
await AsyncCallBenchmark('Calls.AwaitFutureOrCall', performAwaitFutureOrCalls)
|
|
.report();
|
|
await AsyncCallBenchmark('Calls.AwaitFutureOrCallClosureTargetPolymorphic',
|
|
() => performAwaitCallsClosureTargetPolymorphic(returnFutureOr)).report();
|
|
await AsyncCallBenchmark('Calls.AwaitFutureOrCallInstanceTargetPolymorphic',
|
|
() => performAwaitFutureOrCallsInstanceTargetPolymorphic(target))
|
|
.report();
|
|
await AsyncCallBenchmark(
|
|
'Calls.AwaitFutureOrCallInstanceTargetPolymorphicManyAwaits',
|
|
() =>
|
|
performAwaitAsyncCallsInstanceTargetPolymorphicManyAwaits(target))
|
|
.report();
|
|
|
|
await AsyncCallBenchmark('Calls.AwaitForAsyncStarStreamPolymorphic',
|
|
() => performAwaitForIterationPolymorphic(generateNumbersAsyncStar))
|
|
.report();
|
|
await AsyncCallBenchmark(
|
|
'Calls.AwaitForAsyncStarStreamPolymorphicManyYields',
|
|
() => performAwaitForIterationPolymorphic(
|
|
generateNumbersAsyncStarManyYields)).report();
|
|
await AsyncCallBenchmark('Calls.AwaitForManualStreamPolymorphic',
|
|
() => performAwaitForIterationPolymorphic(generateNumbersManualAsync))
|
|
.report();
|
|
|
|
SyncCallBenchmark('Calls.SyncCall', performSyncCalls).report();
|
|
SyncCallBenchmark('Calls.SyncCallClosureTarget',
|
|
() => performSyncCallsClosureTarget(returnSync)).report();
|
|
SyncCallBenchmark('Calls.SyncCallInstanceTargetPolymorphic',
|
|
() => performSyncCallsInstanceTargetPolymorphic(target)).report();
|
|
|
|
SyncCallBenchmark('Calls.IterableSyncStarIterablePolymorphic',
|
|
() => performSyncIterationPolymorphic(generateNumbersSyncStar)).report();
|
|
SyncCallBenchmark('Calls.IterableManualIterablePolymorphic',
|
|
() => performSyncIterationPolymorphic(generateNumbersManual)).report();
|
|
SyncCallBenchmark(
|
|
'Calls.IterableManualIterablePolymorphicManyYields',
|
|
() => performSyncIterationPolymorphic(
|
|
generateNumbersSyncStarManyYields)).report();
|
|
}
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Future<int> performAwaitCallsClosureTargetPolymorphic(
|
|
FutureOr<int> Function(int) fun) async {
|
|
int sum = 0;
|
|
for (int i = 0; i < iterationLimitAsync; ++i) {
|
|
sum += await fun(i);
|
|
}
|
|
if (sum != sumOfIterationLimitAsync) throw 'BUG';
|
|
return iterationLimitAsync;
|
|
}
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Future<int> performAwaitAsyncCallsInstanceTargetPolymorphic(
|
|
Target target) async {
|
|
int sum = 0;
|
|
for (int i = 0; i < iterationLimitAsync; ++i) {
|
|
sum += await target.returnAsync(i);
|
|
}
|
|
if (sum != sumOfIterationLimitAsync) throw 'BUG';
|
|
return iterationLimitAsync;
|
|
}
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Future<int> performAwaitFutureCallsInstanceTargetPolymorphic(
|
|
Target target) async {
|
|
int sum = 0;
|
|
for (int i = 0; i < iterationLimitAsync; ++i) {
|
|
sum += await target.returnFuture(i);
|
|
}
|
|
if (sum != sumOfIterationLimitAsync) throw 'BUG';
|
|
return iterationLimitAsync;
|
|
}
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Future<int> performAwaitFutureOrCallsInstanceTargetPolymorphic(
|
|
Target target) async {
|
|
int sum = 0;
|
|
for (int i = 0; i < iterationLimitAsync; ++i) {
|
|
sum += await target.returnFutureOr(i);
|
|
}
|
|
if (sum != sumOfIterationLimitAsync) throw 'BUG';
|
|
return iterationLimitAsync;
|
|
}
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Future<int> performAwaitAsyncCalls() async {
|
|
int sum = 0;
|
|
for (int i = 0; i < iterationLimitAsync; ++i) {
|
|
sum += await returnAsync(i);
|
|
}
|
|
if (sum != sumOfIterationLimitAsync) throw 'BUG';
|
|
return iterationLimitAsync;
|
|
}
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Future<int> performAwaitFutureCalls() async {
|
|
int sum = 0;
|
|
for (int i = 0; i < iterationLimitAsync; ++i) {
|
|
sum += await returnFuture(i);
|
|
}
|
|
if (sum != sumOfIterationLimitAsync) throw 'BUG';
|
|
return iterationLimitAsync;
|
|
}
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Future<int> performAwaitFutureOrCalls() async {
|
|
int sum = 0;
|
|
for (int i = 0; i < iterationLimitAsync; ++i) {
|
|
sum += await returnFutureOr(i);
|
|
}
|
|
if (sum != sumOfIterationLimitAsync) throw 'BUG';
|
|
return iterationLimitAsync;
|
|
}
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Future<int> performAwaitAsyncCallsInstanceTargetPolymorphicManyAwaits(
|
|
Target t) async {
|
|
int sum = 0;
|
|
int i = 0;
|
|
|
|
final int blockLimit = iterationLimitAsync - (iterationLimitAsync % 80);
|
|
while (i < blockLimit) {
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
sum += await t.returnAsync(i++);
|
|
}
|
|
|
|
while (i < iterationLimitAsync) {
|
|
sum += await t.returnAsync(i++);
|
|
}
|
|
|
|
if (sum != sumOfIterationLimitAsync) throw 'BUG';
|
|
|
|
return iterationLimitAsync;
|
|
}
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Future<int> performAwaitForIterationPolymorphic(
|
|
Stream<int> Function(int) fun) async {
|
|
int sum = 0;
|
|
await for (int value in fun(iterationLimitAsync)) {
|
|
sum += value;
|
|
}
|
|
if (sum != sumOfIterationLimitAsync) throw 'BUG';
|
|
return iterationLimitAsync;
|
|
}
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
int performSyncCallsClosureTarget(int Function(int) fun) {
|
|
int sum = 0;
|
|
for (int i = 0; i < iterationLimitSync; ++i) {
|
|
sum += fun(i);
|
|
}
|
|
if (sum != sumOfIterationLimitSync) throw 'BUG';
|
|
return iterationLimitSync;
|
|
}
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
int performSyncCallsInstanceTargetPolymorphic(Target target) {
|
|
int sum = 0;
|
|
for (int i = 0; i < iterationLimitSync; ++i) {
|
|
sum += target.returnSync(i);
|
|
}
|
|
if (sum != sumOfIterationLimitSync) throw 'BUG';
|
|
return iterationLimitSync;
|
|
}
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
int performSyncCalls() {
|
|
int sum = 0;
|
|
for (int i = 0; i < iterationLimitSync; ++i) {
|
|
sum += returnSync(i);
|
|
}
|
|
if (sum != sumOfIterationLimitSync) throw 'BUG';
|
|
return iterationLimitSync;
|
|
}
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
int performSyncIterationPolymorphic(Iterable<int> Function(int) fun) {
|
|
int sum = 0;
|
|
for (int value in fun(iterationLimitSync)) {
|
|
sum += value;
|
|
}
|
|
if (sum != sumOfIterationLimitSync) throw 'BUG';
|
|
return iterationLimitSync;
|
|
}
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
FutureOr<int> returnFutureOr(int i) => i;
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Future<int> returnFuture(int i) => Future.value(i);
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Future<int> returnAsync(int i) async => i;
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Stream<int> generateNumbersAsyncStar(int limit) async* {
|
|
for (int i = 0; i < limit; ++i) {
|
|
yield i;
|
|
}
|
|
}
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Stream<int> generateNumbersAsyncStar2(int limit) async* {
|
|
for (int i = 0; i < limit; ++i) {
|
|
yield i;
|
|
}
|
|
}
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Stream<int> generateNumbersManualAsync(int limit) {
|
|
int current = 0;
|
|
final controller = StreamController<int>(sync: true);
|
|
void emit() {
|
|
while (true) {
|
|
if (controller.isPaused || !controller.hasListener) return;
|
|
if (current < limit) {
|
|
controller.add(current++);
|
|
} else {
|
|
controller.close();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void run() {
|
|
scheduleMicrotask(emit);
|
|
}
|
|
|
|
controller.onListen = run;
|
|
controller.onResume = run;
|
|
|
|
return controller.stream;
|
|
}
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
int returnSync(int i) => i;
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Iterable<int> generateNumbersSyncStar(int limit) sync* {
|
|
for (int i = 0; i < limit; ++i) {
|
|
yield i;
|
|
}
|
|
}
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Iterable<int> generateNumbersSyncStar2(int limit) sync* {
|
|
for (int i = 0; i < limit; ++i) {
|
|
yield i;
|
|
}
|
|
}
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Iterable<int> generateNumbersManual(int limit) =>
|
|
Iterable<int>.generate(limit, (int i) => i);
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Iterable<int> generateNumbersSyncStarManyYields(int limit) sync* {
|
|
int i = 0;
|
|
|
|
final int blockLimit = limit - (limit % (20 * 7));
|
|
while (i < blockLimit) {
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
}
|
|
|
|
while (i < limit) {
|
|
yield i++;
|
|
}
|
|
}
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Stream<int> generateNumbersAsyncStarManyYields(int limit) async* {
|
|
int i = 0;
|
|
|
|
final int blockLimit = limit - (limit % (20 * 7));
|
|
while (i < blockLimit) {
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
yield i++;
|
|
}
|
|
|
|
while (i < limit) {
|
|
yield i++;
|
|
}
|
|
}
|
|
|
|
class Target {
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
FutureOr<int> returnFutureOr(int i) => i;
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Future<int> returnFuture(int i) => Future.value(i);
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Future<int> returnAsync(int i) async => i;
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
int returnSync(int i) => i;
|
|
}
|
|
|
|
class Target2 extends Target {
|
|
@override
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
FutureOr<int> returnFutureOr(int i) => i;
|
|
|
|
@override
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Future<int> returnFuture(int i) => Future.value(i);
|
|
|
|
@override
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Future<int> returnAsync(int i) async => i;
|
|
|
|
@override
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
int returnSync(int i) => i;
|
|
}
|
|
|
|
class Target3 extends Target {
|
|
@override
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
FutureOr<int> returnFutureOr(int i) => i;
|
|
|
|
@override
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Future<int> returnFuture(int i) => Future.value(i);
|
|
|
|
@override
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Future<int> returnAsync(int i) async => i;
|
|
|
|
@override
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
int returnSync(int i) => i;
|
|
}
|
|
|
|
typedef PerformSyncCallsFunction = int Function();
|
|
typedef PerformAsyncCallsFunction = Future<int> Function();
|
|
|
|
class SyncCallBenchmark {
|
|
final String name;
|
|
final PerformSyncCallsFunction performCalls;
|
|
|
|
SyncCallBenchmark(this.name, this.performCalls);
|
|
|
|
// Returns the number of nanoseconds per call.
|
|
double measureFor(Duration duration) {
|
|
final sw = Stopwatch()..start();
|
|
final durationInMicroseconds = duration.inMicroseconds;
|
|
|
|
int numberOfCalls = 0;
|
|
int totalMicroseconds = 0;
|
|
do {
|
|
numberOfCalls += performCalls();
|
|
totalMicroseconds = sw.elapsedMicroseconds;
|
|
} while (totalMicroseconds < durationInMicroseconds);
|
|
|
|
final int totalNanoseconds = sw.elapsed.inMicroseconds * 1000;
|
|
return totalNanoseconds / numberOfCalls;
|
|
}
|
|
|
|
// Runs warmup phase, runs benchmark and reports result.
|
|
void report() {
|
|
// Warmup for 100 ms.
|
|
measureFor(const Duration(milliseconds: 100));
|
|
|
|
// Run benchmark for 2 seconds.
|
|
final double nsPerCall = measureFor(const Duration(seconds: 2));
|
|
|
|
// Report result.
|
|
print('$name(RunTimeRaw): $nsPerCall ns.');
|
|
}
|
|
}
|
|
|
|
class AsyncCallBenchmark {
|
|
final String name;
|
|
final PerformAsyncCallsFunction performCalls;
|
|
|
|
AsyncCallBenchmark(this.name, this.performCalls);
|
|
|
|
// Returns the number of nanoseconds per call.
|
|
Future<double> measureFor(Duration duration) async {
|
|
final sw = Stopwatch()..start();
|
|
final durationInMicroseconds = duration.inMicroseconds;
|
|
|
|
int numberOfCalls = 0;
|
|
int totalMicroseconds = 0;
|
|
do {
|
|
numberOfCalls += await performCalls();
|
|
totalMicroseconds = sw.elapsedMicroseconds;
|
|
} while (totalMicroseconds < durationInMicroseconds);
|
|
|
|
final int totalNanoseconds = sw.elapsed.inMicroseconds * 1000;
|
|
return totalNanoseconds / numberOfCalls;
|
|
}
|
|
|
|
// Runs warmup phase, runs benchmark and reports result.
|
|
Future report() async {
|
|
// Warmup for 100 ms.
|
|
await measureFor(const Duration(milliseconds: 100));
|
|
|
|
// Run benchmark for 2 seconds.
|
|
final double nsPerCall = await measureFor(const Duration(seconds: 2));
|
|
|
|
// Report result.
|
|
print('$name(RunTimeRaw): $nsPerCall ns.');
|
|
}
|
|
}
|