blob: fb9f5677bfe966995f4e103f058aa50a54019634 [file] [log] [blame]
// 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.');
}
}