// 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. // @dart=2.9 import 'dart:collection'; import 'dart:typed_data'; import 'package:benchmark_harness/benchmark_harness.dart'; import 'sound_splay_tree.dart'; List sieve(List initialCandidates) { final candidates = SplayTreeSet.from(initialCandidates); final int last = candidates.last; final primes = []; // ignore: literal_only_boolean_expressions while (true) { final int prime = candidates.first; if (prime * prime > last) break; primes.add(prime); for (int i = prime; i <= last; i += prime) { candidates.remove(i); } } return primes..addAll(candidates); } List sieveSound(List initialCandidates) { final candidates = SoundSplayTreeSet.from(initialCandidates); final int last = candidates.last; final primes = []; // ignore: literal_only_boolean_expressions while (true) { final int prime = candidates.first; if (prime * prime > last) break; primes.add(prime); for (int i = prime; i <= last; i += prime) { candidates.remove(i); } } return primes..addAll(candidates); } /// Returns a list of integers from [first] to [last], both inclusive. List range(int first, int last) { return List.generate(last - first + 1, (int i) => i + first); } int id(int x) => x; int add1(int i) => 1 + i; bool isEven(int i) => i.isEven; void exercise(Iterable hello) { if (hello.toList().length != 5) throw 'x1'; if (List.from(hello).length != 5) throw 'x1'; if (Set.from(hello).length != 4) throw 'x1'; if (List.from(hello).where(isEven).length != 3) throw 'x1'; if (hello.where(isEven).length != 3) throw 'x1'; if (hello.map(add1).where(isEven).length != 2) throw 'x1'; if (hello.where(isEven).map(add1).length != 3) throw 'x1'; } void busyWork() { // A lot of busy-work calling map/where/toList/List.from to ensure the core // library is used with some degree of polymorphism. final L1 = 'hello'.codeUnits; final L2 = Uint16List(5)..setRange(0, 5, L1); final L3 = Uint32List(5)..setRange(0, 5, L1); exercise(L1); exercise(L2); exercise(L3); exercise(UnmodifiableListView(L1)); exercise(UnmodifiableListView(L2)); exercise(UnmodifiableListView(L3)); exercise(L1.asMap().values); exercise(L1.toList().asMap().values); final M1 = Map.fromIterables(['a', 'b', 'c', 'd', 'e'], L1); final M2 = const { 'a': 104, 'b': 101, 'c': 108, 'd': 108, 'e': 111 }; exercise(M1.values); exercise(M2.values); } main() { final benchmarks = [ Base(sieve, 'CollectionSieves-SplayTreeSet-removeLoop'), Base(sieveSound, 'CollectionSieves-SoundSplayTreeSet-removeLoop'), ]; for (int i = 0; i < 10; i++) { busyWork(); for (var bm in benchmarks) { bm.run(); } } for (var bm in benchmarks) { bm.report(); } } class Base extends BenchmarkBase { final algorithm; Base(this.algorithm, String name) : super(name); static final input = range(2, 5000); void run() { final primes = algorithm(input); if (primes.length != 669) throw 'Wrong result for $name: ${primes.length}'; } }