mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 02:07:06 +00:00
b341480a72
This benchmark tests the performance of uninstantiated type literal usages. Issue https://github.com/dart-lang/sdk/issues/48757 TEST=ci Change-Id: I5eb881a2b8e397997505af41b24240afcbe9d1ac Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/242104 Reviewed-by: Alexander Markov <alexmarkov@google.com> Commit-Queue: Martin Kustermann <kustermann@google.com>
198 lines
5.5 KiB
Dart
198 lines
5.5 KiB
Dart
// Copyright (c) 2022, 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.
|
|
|
|
const int iterations = 100000;
|
|
|
|
void main() {
|
|
SyncCallBenchmark('TypeLiteral.GenericFunction.T.dynamic', () {
|
|
for (int i = 0; i < iterations; ++i) {
|
|
getT<dynamic>();
|
|
}
|
|
return iterations;
|
|
}).report();
|
|
SyncCallBenchmark('TypeLiteral.GenericFunction.T.int', () {
|
|
for (int i = 0; i < iterations; ++i) {
|
|
getT<int>();
|
|
}
|
|
return iterations;
|
|
}).report();
|
|
SyncCallBenchmark('TypeLiteral.GenericFunction.T.nullableInt', () {
|
|
for (int i = 0; i < iterations; ++i) {
|
|
getT<int?>();
|
|
}
|
|
return iterations;
|
|
}).report();
|
|
SyncCallBenchmark('TypeLiteral.GenericFunction.ListOfT.int', () {
|
|
for (int i = 0; i < iterations; ++i) {
|
|
getListOfT<int>();
|
|
}
|
|
return iterations;
|
|
}).report();
|
|
SyncCallBenchmark('TypeLiteral.GenericFunction.ListOfT.nullableInt', () {
|
|
for (int i = 0; i < iterations; ++i) {
|
|
getListOfT<int?>();
|
|
}
|
|
return iterations;
|
|
}).report();
|
|
SyncCallBenchmark('TypeLiteral.GenericFunction.NullableT.int', () {
|
|
for (int i = 0; i < iterations; ++i) {
|
|
getNullableT<int>();
|
|
}
|
|
return iterations;
|
|
}).report();
|
|
SyncCallBenchmark('TypeLiteral.GenericFunction.NullableT.nullableInt', () {
|
|
for (int i = 0; i < iterations; ++i) {
|
|
getNullableT<int?>();
|
|
}
|
|
return iterations;
|
|
}).report();
|
|
SyncCallBenchmark('TypeLiteral.GenericFunction.ListOfNullableT.int', () {
|
|
for (int i = 0; i < iterations; ++i) {
|
|
getListOfT<int>();
|
|
}
|
|
return iterations;
|
|
}).report();
|
|
SyncCallBenchmark('TypeLiteral.GenericFunction.ListOfNullableT.nullableInt',
|
|
() {
|
|
for (int i = 0; i < iterations; ++i) {
|
|
getListOfNullableT<int?>();
|
|
}
|
|
return iterations;
|
|
}).report();
|
|
final foos = <Foo<Object?>>[
|
|
Foo<int>(),
|
|
Foo<int?>(),
|
|
Foo<dynamic>(),
|
|
];
|
|
final Foo fooInt = foos[int.parse('0')];
|
|
final Foo fooNullableInt = foos[int.parse('1')];
|
|
final Foo fooDynamic = foos[int.parse('2')];
|
|
SyncCallBenchmark('TypeLiteral.GenericClass.T.dynamic', () {
|
|
for (int i = 0; i < iterations; ++i) {
|
|
fooDynamic.getT();
|
|
}
|
|
return iterations;
|
|
}).report();
|
|
SyncCallBenchmark('TypeLiteral.GenericClass.T.int', () {
|
|
for (int i = 0; i < iterations; ++i) {
|
|
fooInt.getT();
|
|
}
|
|
return iterations;
|
|
}).report();
|
|
SyncCallBenchmark('TypeLiteral.GenericClass.T.nullableInt', () {
|
|
for (int i = 0; i < iterations; ++i) {
|
|
fooNullableInt.getT();
|
|
}
|
|
return iterations;
|
|
}).report();
|
|
SyncCallBenchmark('TypeLiteral.GenericClass.ListOfT.int', () {
|
|
for (int i = 0; i < iterations; ++i) {
|
|
fooInt.getListOfT();
|
|
}
|
|
return iterations;
|
|
}).report();
|
|
SyncCallBenchmark('TypeLiteral.GenericClass.ListOfT.nullableInt', () {
|
|
for (int i = 0; i < iterations; ++i) {
|
|
fooNullableInt.getListOfT();
|
|
}
|
|
return iterations;
|
|
}).report();
|
|
SyncCallBenchmark('TypeLiteral.GenericClass.NullableT.int', () {
|
|
for (int i = 0; i < iterations; ++i) {
|
|
fooInt.getNullableT();
|
|
}
|
|
return iterations;
|
|
}).report();
|
|
SyncCallBenchmark('TypeLiteral.GenericClass.NullableT.nullableInt', () {
|
|
for (int i = 0; i < iterations; ++i) {
|
|
fooNullableInt.getNullableT();
|
|
}
|
|
return iterations;
|
|
}).report();
|
|
SyncCallBenchmark('TypeLiteral.GenericClass.ListOfNullableT.int', () {
|
|
for (int i = 0; i < iterations; ++i) {
|
|
fooInt.getListOfT();
|
|
}
|
|
return iterations;
|
|
}).report();
|
|
SyncCallBenchmark('TypeLiteral.GenericClass.ListOfNullableT.nullableInt', () {
|
|
for (int i = 0; i < iterations; ++i) {
|
|
fooNullableInt.getListOfNullableT();
|
|
}
|
|
return iterations;
|
|
}).report();
|
|
}
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Type getT<T>() => T;
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Type getNullableT<T>() => MakeNullable<T?>;
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Type getListOfT<T>() => List<T>;
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Type getListOfNullableT<T>() => List<T?>;
|
|
|
|
class Foo<T> {
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Type getT() => T;
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Type getNullableT() => MakeNullable<T?>;
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Type getListOfT() => List<T>;
|
|
|
|
@pragma('vm:never-inline')
|
|
@pragma('dart2js:noInline')
|
|
Type getListOfNullableT() => List<T?>;
|
|
}
|
|
|
|
typedef MakeNullable<X> = X?;
|
|
|
|
// Same as from [Calls] benchmark.
|
|
class SyncCallBenchmark {
|
|
final String name;
|
|
final int Function() 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.');
|
|
}
|
|
}
|