mirror of
https://github.com/dart-lang/sdk
synced 2024-10-01 19:14:49 +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>
132 lines
3.2 KiB
Dart
132 lines
3.2 KiB
Dart
// Copyright (c) 2021, 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.
|
|
|
|
// Benchmark for https://github.com/dart-lang/sdk/issues/45908.
|
|
//
|
|
// Measures the average time needed for a lookup in Maps.
|
|
|
|
import 'dart:math';
|
|
|
|
import 'maps.dart';
|
|
|
|
abstract class MapLookupBenchmark {
|
|
final String name;
|
|
const MapLookupBenchmark(this.name);
|
|
|
|
Map<String, String> get myMap;
|
|
|
|
// Returns the number of nanoseconds per call.
|
|
double measureFor(Duration duration) {
|
|
final map = myMap;
|
|
|
|
// Prevent `sw.elapsedMicroseconds` from dominating with maps with a
|
|
// small number of elements.
|
|
final int batching = max(1000 ~/ map.length, 1);
|
|
|
|
int numberOfLookups = 0;
|
|
int totalMicroseconds = 0;
|
|
|
|
final sw = Stopwatch()..start();
|
|
final durationInMicroseconds = duration.inMicroseconds;
|
|
|
|
do {
|
|
for (int i = 0; i < batching; i++) {
|
|
String? k = '0';
|
|
while (k != null) {
|
|
k = map[k];
|
|
}
|
|
numberOfLookups += map.length;
|
|
}
|
|
totalMicroseconds = sw.elapsedMicroseconds;
|
|
} while (totalMicroseconds < durationInMicroseconds);
|
|
|
|
final int totalNanoseconds = sw.elapsed.inMicroseconds * 1000;
|
|
return totalNanoseconds / numberOfLookups;
|
|
}
|
|
|
|
// 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 Constant1 extends MapLookupBenchmark {
|
|
const Constant1() : super('MapLookup.Constant1');
|
|
|
|
@override
|
|
Map<String, String> get myMap => const1;
|
|
}
|
|
|
|
class Final1 extends MapLookupBenchmark {
|
|
const Final1() : super('MapLookup.Final1');
|
|
|
|
@override
|
|
Map<String, String> get myMap => final1;
|
|
}
|
|
|
|
class Constant5 extends MapLookupBenchmark {
|
|
const Constant5() : super('MapLookup.Constant5');
|
|
|
|
@override
|
|
Map<String, String> get myMap => const5;
|
|
}
|
|
|
|
class Final5 extends MapLookupBenchmark {
|
|
const Final5() : super('MapLookup.Final5');
|
|
|
|
@override
|
|
Map<String, String> get myMap => final5;
|
|
}
|
|
|
|
class Constant10 extends MapLookupBenchmark {
|
|
const Constant10() : super('MapLookup.Constant10');
|
|
|
|
@override
|
|
Map<String, String> get myMap => const10;
|
|
}
|
|
|
|
class Final10 extends MapLookupBenchmark {
|
|
const Final10() : super('MapLookup.Final10');
|
|
|
|
@override
|
|
Map<String, String> get myMap => final10;
|
|
}
|
|
|
|
class Constant100 extends MapLookupBenchmark {
|
|
const Constant100() : super('MapLookup.Constant100');
|
|
|
|
@override
|
|
Map<String, String> get myMap => const100;
|
|
}
|
|
|
|
class Final100 extends MapLookupBenchmark {
|
|
const Final100() : super('MapLookup.Final100');
|
|
|
|
@override
|
|
Map<String, String> get myMap => final100;
|
|
}
|
|
|
|
void main() {
|
|
final benchmarks = [
|
|
() => const Constant1(),
|
|
() => const Constant5(),
|
|
() => const Constant10(),
|
|
() => const Constant100(),
|
|
() => const Final1(),
|
|
() => const Final5(),
|
|
() => const Final10(),
|
|
() => const Final100(),
|
|
];
|
|
for (final benchmark in benchmarks) {
|
|
benchmark().report();
|
|
}
|
|
}
|