From bb2d193aafcbfe2bfd42d16bb93fb6b8c5cd29cb Mon Sep 17 00:00:00 2001 From: Stephen Adams Date: Thu, 10 Feb 2022 18:38:41 +0000 Subject: [PATCH] Add system list polymorphism cases in Iterators benchmark Change-Id: Iee3d126370d314609cd25c8ac015fc360c9ae16f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/232202 Reviewed-by: Martin Kustermann Commit-Queue: Stephen Adams --- benchmarks/Iterators/dart/Iterators.dart | 56 +++++++++ benchmarks/Iterators/dart/data.dart | 138 +++++++---------------- 2 files changed, 94 insertions(+), 100 deletions(-) diff --git a/benchmarks/Iterators/dart/Iterators.dart b/benchmarks/Iterators/dart/Iterators.dart index b58e8808102..d4ff6c41089 100644 --- a/benchmarks/Iterators/dart/Iterators.dart +++ b/benchmarks/Iterators/dart/Iterators.dart @@ -331,6 +331,60 @@ class BenchmarkListIntGrowable extends MonoBenchmark { } } +class BenchmarkListIntSystem1 extends MonoBenchmark { + // The List type here is not quite monomorphic. It is the choice between two + // 'system' Lists: a const List and a growable List. It is quite common to + // have growable and const lists at the same use-site (e.g. the const coming + // from a default argument). + // + // Ideally some combination of the class heirarchy or compiler tricks would + // ensure there is little cost of having this gentle polymorphism. + BenchmarkListIntSystem1(int size) + : _list1 = List.generate(size, (i) => i), + _list2 = generateConstListOfInt(size), + super('List.int.growable.and.const', size); + + final List _list1; + final List _list2; + bool _flip = false; + + @override + void sinkMono() { + _flip = !_flip; + final list = _flip ? _list1 : _list2; + for (final value in list) { + sink = value; + } + } +} + +class BenchmarkListIntSystem2 extends MonoBenchmark { + // The List type here is not quite monomorphic. It is the choice between two + // 'system' Lists: a const List and a fixed-length List. It is quite common to + // have fixed-length and const lists at the same use-site (e.g. the const + // coming from a default argument). + // + // Ideally some combination of the class heirarchy or compiler tricks would + // ensure there is little cost of having this gentle polymorphism. + BenchmarkListIntSystem2(int size) + : _list1 = List.generate(size, (i) => i, growable: false), + _list2 = generateConstListOfInt(size), + super('List.int.fixed.and.const', size); + + final List _list1; + final List _list2; + bool _flip = false; + + @override + void sinkMono() { + _flip = !_flip; + final list = _flip ? _list1 : _list2; + for (final value in list) { + sink = value; + } + } +} + /// A simple Iterable that yields the integers 0 through `length`. /// /// This Iterable serves as the minimal interesting example to serve as a @@ -492,6 +546,8 @@ void main(List commandLineArguments) { Benchmark('Runes', size, (n) => generateString(n).runes), // --- BenchmarkListIntGrowable(size), + BenchmarkListIntSystem1(size), + BenchmarkListIntSystem2(size), Benchmark('List.int.growable', size, (n) => List.of(UpTo(n), growable: true)), Benchmark('List.int.fixed', size, diff --git a/benchmarks/Iterators/dart/data.dart b/benchmarks/Iterators/dart/data.dart index eabe7f4d721..f59c26f8d7c 100644 --- a/benchmarks/Iterators/dart/data.dart +++ b/benchmarks/Iterators/dart/data.dart @@ -12,6 +12,11 @@ Set generateConstSetOfInt(int n) { (throw ArgumentError.value(n, 'n', 'size not supported')); } +List generateConstListOfInt(int n) { + return constListOfIntTable[n] ?? + (throw ArgumentError.value(n, 'n', 'size not supported')); +} + const Map> constMapIntIntTable = { 0: constMapIntInt0, 1: constMapIntInt1, @@ -136,104 +141,37 @@ const Set constSetOfInt0 = {}; const Set constSetOfInt1 = {0}; const Set constSetOfInt2 = {0, 1}; const Set constSetOfInt100 = { - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - 64, - 65, - 66, - 67, - 68, - 69, - 70, - 71, - 72, - 73, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87, - 88, - 89, - 90, - 91, - 92, - 93, - 94, - 95, - 96, - 97, - 98, - 99 + ...{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, + ...{10, 11, 12, 13, 14, 15, 16, 17, 18, 19}, + ...{20, 21, 22, 23, 24, 25, 26, 27, 28, 29}, + ...{30, 31, 32, 33, 34, 35, 36, 37, 38, 39}, + ...{40, 41, 42, 43, 44, 45, 46, 47, 48, 49}, + ...{50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, + ...{60, 61, 62, 63, 64, 65, 66, 67, 68, 69}, + ...{70, 71, 72, 73, 74, 75, 76, 77, 78, 79}, + ...{80, 81, 82, 83, 84, 85, 86, 87, 88, 89}, + ...{90, 91, 92, 93, 94, 95, 96, 97, 98, 99} }; + +const Map> constListOfIntTable = { + 0: constListOfInt0, + 1: constListOfInt1, + 2: constListOfInt2, + 100: constListOfInt100 +}; + +const List constListOfInt0 = []; +const List constListOfInt1 = [0]; +const List constListOfInt2 = [0, 1]; +const List constListOfInt100 = [ + ...[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], + ...[10, 11, 12, 13, 14, 15, 16, 17, 18, 19], + ...[20, 21, 22, 23, 24, 25, 26, 27, 28, 29], + ...[30, 31, 32, 33, 34, 35, 36, 37, 38, 39], + ...[40, 41, 42, 43, 44, 45, 46, 47, 48, 49], + ...[50, 51, 52, 53, 54, 55, 56, 57, 58, 59], + ...[60, 61, 62, 63, 64, 65, 66, 67, 68, 69], + ...[70, 71, 72, 73, 74, 75, 76, 77, 78, 79], + ...[80, 81, 82, 83, 84, 85, 86, 87, 88, 89], + ...[90, 91, 92, 93, 94, 95, 96, 97, 98, 99] +];