// 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.

/// # Benchmark for iterators of common collections.
///
/// The purpose of this benchmark is to detect performance changes in the
/// iterators for common collections (system Lists, Maps, etc).
///
/// ## Polymorphic benchmarks
///
/// Benchmark names beginning with `Iterators.poly.`.
///
/// These benchmark use the iterators from a common polymorphic for-in loop, so
/// none of the methods involved in iterating are inlined. This gives an
/// indication of worst-case performance.
///
/// Iterables of different sizes (small (N=1) and large (N=100)) are used to
/// give insight into the fixed vs per-element costs.
///
/// Results are normalized by iterating 1000 elements and reporting the time per
/// element. There is an outer loop that calls the iterator loop in `sinkAll`.
///
/// The dispatched (polymorphic) calls are to `get:iterator`, `moveNext` and
/// `get:current`.
///
///  |    N | outer | `get:iterator` | `moveNext` | `get:current` |
///  | ---: | ----: | -------------: | ---------: | ------------: |
///  |   0* |  1000 |           1000 |       1000 |             0 |
///  |   1  |  1000 |           1000 |       2000 |          1000 |
///  |   2* |   500 |            500 |       1500 |          1000 |
///  | 100  |    10 |             10 |       1010 |          1000 |
///
/// * By default only the N=1 and N=100 benchmarks arer run. The N=0 and N=2
/// series are available running manually with `--0` and `--2` command-line
/// arguments.
///
/// Generic Iterables have benchmarks for different element types. There are
/// benchmarks for `int` type arguments, which have a fast type test, and for
/// `Thing<Iterable<Comparable>>`, which is harder to test quickly. These tests
/// are distinguished by `int` and `Hard` in the name.
///
/// ## Monomorphic benchmarks
///
/// Benchmark names beginning with `Iterators.mono.`.
///
/// A subset of the polymorphic benchmarks are also implemented with a
/// per-benchmark for-in loop directly iterating a collection of known
/// representation. This gives the compiler the opportunity to inline the
/// methods into the loop and represents the best-case performance.
///
/// ## Example benchmarks
///
/// The name has 4-7 words separated by periods. The first word is always
/// 'Iterators', and the second is either 'mono' for monomorphic loops, or
/// 'poly' for benchmarks using a shared polymorphic loop. The last word is a
/// number which is the size (length) of the Iterable.
///
/// ### Iterators.mono.const.Map.int.values.100
///
/// A for-in loop over the values iterable of a known constant Map with value
/// type `int` and 100 entries.
///
/// ### Iterators.poly.Runes.1
///
/// An iteration over the String.runes iterable of a single character String
/// using the shared polymorphic loop.
///
/// ### Iterators.poly.HashMap.Hard.keys.100
///
/// An iteration of over the keys iterable of a HashMap with key type
/// `Thing<Iterable<Comparable>>` and 100 entries.
///
/// ### Iterators.*.UpTo.*
///
/// The UpTo iterable is a minimal iterable that provides successive
/// numbers. The `moveNext` and `get:current` methods are small. Comparing
/// Iterators.poly.UpTo.*.100 to Iterators.poly.*.100 gives an indication of how
/// much work is done by `moveNext` (and sometimes `get:current`).
///
/// ### Iterators.mono.Nothing.*
///
/// The Nothing benchmark has no iteration over an iterable and is used to get a
/// baseline time for running the benchmark loop for monomorphic
/// benchmarks. This can be a substantial fraction of
///
/// Consider the times
///
///     Iterators.mono.CodeUnits.1   = 7.0ns
///     Iterators.mono.Nothing.1     = 3.1ns
///
/// Because the trip count (i.e. 1) of the for-in loop is so small, there is a
/// lot of overhead attributable to the outer loop in `MonoBenchmark.run`. The
/// 1000/1 = 1000 trips of outer loops takes 3.1us (3.1ns * 1000 trips), so
/// CodeUnits is spending only 7.0-3.1 = 3.9ns per character in the for-in
/// loop over the `.codeUnits` of the single-character String.
///
///     Iterators.mono.CodeUnits.100 = 1.83ns
///     Iterators.mono.Nothing.100   = 0.05ns
///
/// Now the outer loop runs only 1000/100 = 10 times, for 0.05us. If we subtract
/// this from 1.83, we get 1.78ns per character for long strings.
///
library iterators_benchmark;

// TODO(48277): Update when fixed:
// ignore_for_file: unnecessary_lambdas

import 'dart:collection';

import 'package:benchmark_harness/benchmark_harness.dart';

import 'data.dart';

const targetSize = 1000;

class Emitter implements ScoreEmitter {
  @override
  void emit(String testName, double value) {
    // [value] is microseconds per ten calls to `run()`.
    final nanoSeconds = value * 1000;
    final singleElementTimeNs = nanoSeconds / 10 / targetSize;
    print('$testName(RunTimeRaw): $singleElementTimeNs ns.');
  }
}

abstract class Benchmark extends BenchmarkBase {
  final int size;
  bool selected = false;
  Benchmark._(String name, this.size)
      : super('Iterators.$name.$size', emitter: Emitter());

  factory Benchmark(String name, int size, Iterable Function(int) generate) =
      PolyBenchmark;
}

abstract class MonoBenchmark extends Benchmark {
  final int _repeats;
  MonoBenchmark(String name, int size)
      : _repeats = size == 0 ? targetSize : targetSize ~/ size,
        super._('mono.$name', size);

  @override
  void run() {
    for (int i = 0; i < _repeats; i++) {
      sinkMono();
    }
  }

  void sinkMono();
}

class PolyBenchmark extends Benchmark {
  final Iterable Function(int) generate;
  final List<Iterable> inputs = [];

  PolyBenchmark(String name, int size, this.generate)
      : super._('poly.$name', size);

  @override
  void setup() {
    if (inputs.isNotEmpty) return; // Ensure setup() is idempotent.

    int totalSize = 0;
    while (totalSize < targetSize) {
      final sample = generate(size);
      inputs.add(sample);
      totalSize += size == 0 ? 1 : size;
    }
  }

  @override
  void run() {
    for (int i = 0; i < inputs.length; i++) {
      sinkAll(inputs[i]);
    }
  }
}

/// This function is the inner loop of the benchmark.
@pragma('dart2js:noInline')
@pragma('vm:never-inline')
@pragma('wasm:never-inline')
void sinkAll(Iterable iterable) {
  for (final value in iterable) {
    sink = value;
  }
}

Object? sink;

class BenchmarkConstMapIntKeys1 extends MonoBenchmark {
  BenchmarkConstMapIntKeys1() : super('const.Map.int.keys', 1);

  static const _map = constMapIntInt1;

  @override
  void sinkMono() {
    for (final value in _map.keys) {
      sink = value;
    }
  }
}

class BenchmarkConstMapIntKeys2 extends MonoBenchmark {
  BenchmarkConstMapIntKeys2() : super('const.Map.int.keys', 2);

  static const _map = constMapIntInt2;

  @override
  void sinkMono() {
    for (final value in _map.keys) {
      sink = value;
    }
  }
}

class BenchmarkConstMapIntKeys100 extends MonoBenchmark {
  BenchmarkConstMapIntKeys100() : super('const.Map.int.keys', 100);

  static const _map = constMapIntInt100;

  @override
  void sinkMono() {
    for (final value in _map.keys) {
      sink = value;
    }
  }
}

class BenchmarkConstMapIntValues1 extends MonoBenchmark {
  BenchmarkConstMapIntValues1() : super('const.Map.int.values', 1);

  static const _map = constMapIntInt1;

  @override
  void sinkMono() {
    for (final value in _map.values) {
      sink = value;
    }
  }
}

class BenchmarkConstMapIntValues2 extends MonoBenchmark {
  BenchmarkConstMapIntValues2() : super('const.Map.int.values', 2);

  static const _map = constMapIntInt2;

  @override
  void sinkMono() {
    for (final value in _map.values) {
      sink = value;
    }
  }
}

class BenchmarkConstMapIntValues100 extends MonoBenchmark {
  BenchmarkConstMapIntValues100() : super('const.Map.int.values', 100);

  static const _map = constMapIntInt100;

  @override
  void sinkMono() {
    for (final value in _map.values) {
      sink = value;
    }
  }
}

class BenchmarkMapIntKeys extends MonoBenchmark {
  BenchmarkMapIntKeys(int size) : super('Map.int.keys', size) {
    _map.addAll(generateMapIntInt(size));
  }

  final Map<int, int> _map = {};

  @override
  void sinkMono() {
    for (final value in _map.keys) {
      sink = value;
    }
  }
}

class BenchmarkUpTo extends MonoBenchmark {
  BenchmarkUpTo(int size) : super('UpTo', size);

  @override
  void sinkMono() {
    for (final value in UpTo(size)) {
      sink = value;
    }
  }
}

class BenchmarkNothing extends MonoBenchmark {
  BenchmarkNothing(int size) : super('Nothing', size);

  @override
  void sinkMono() {
    sink = size;
  }
}

class BenchmarkCodeUnits extends MonoBenchmark {
  BenchmarkCodeUnits(int size)
      : string = generateString(size),
        super('CodeUnits', size);

  final String string;

  @override
  void sinkMono() {
    for (final value in string.codeUnits) {
      sink = value;
    }
  }
}

class BenchmarkListIntGrowable extends MonoBenchmark {
  BenchmarkListIntGrowable(int size)
      : _list = List.generate(size, (i) => i),
        super('List.int.growable', size);

  final List<int> _list;

  @override
  void sinkMono() {
    for (final value in _list) {
      sink = value;
    }
  }
}

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 hierarchy 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<int> _list1;
  final List<int> _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 hierarchy 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<int> _list1;
  final List<int> _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
/// baseline, and is useful in constructing other benchmark inputs.
class UpTo extends IterableBase<int> {
  final int _length;
  UpTo(this._length);

  @override
  Iterator<int> get iterator => UpToIterator(_length);
}

class UpToIterator implements Iterator<int> {
  final int _length;
  int _position = 0;
  int? _current;

  UpToIterator(this._length);

  @override
  int get current => _current!;

  @override
  bool moveNext() {
    if (_position < _length) {
      _current = _position++;
      return true;
    }
    _current = null;
    return false;
  }
}

/// A `Thing` has a type parameter which makes type tests in the Iterators
/// potentially harder, and equality uses the type parameter, making Iterables
/// that do lookups slower.
class Thing<T> {
  static int _nextIndex = 0;
  final int _index;
  Thing() : _index = _nextIndex++;

  @override
  int get hashCode => _index;

  @override
  bool operator ==(Object other) => other is Thing<T> && other._index == _index;
}

final thingGenerators = [
  // TODO(48277): Use instantiated constructor tear-offs when fixed:
  () => Thing<Set<String>>(),
  () => Thing<Set<Duration>>(),
  () => Thing<Set<BigInt>>(),
  () => Thing<Queue<String>>(),
  () => Thing<Queue<Duration>>(),
  () => Thing<Queue<BigInt>>(),
  () => Thing<List<String>>(),
  () => Thing<List<Duration>>(),
  () => Thing<List<BigInt>>(),
];

int _generateThingListState = 0;
List<Thing<Iterable<Comparable>>> generateThingList(int n) {
  Thing nextThing(_) {
    final next = (_generateThingListState++).remainder(thingGenerators.length);
    return thingGenerators[next]();
  }

  return List.from(UpTo(n).map(nextThing));
}

Map<Thing<Iterable<Comparable>>, Thing<Iterable<Comparable>>> generateThingMap(
    int n) {
  return Map.fromIterables(generateThingList(n), generateThingList(n));
}

Map<Thing<Iterable<Comparable>>, Thing<Iterable<Comparable>>>
    generateThingHashMap(int n) {
  return HashMap.fromIterables(generateThingList(n), generateThingList(n));
}

int _generateStringState = 0;
String generateString(int n) {
  return ((_generateStringState++).isEven ? 'x' : '\u2192') * n;
}

Map<int, int> generateMapIntInt(int n) =>
    Map<int, int>.fromIterables(UpTo(n), UpTo(n));

Map<int, int> generateIdentityMapIntInt(int n) {
  return Map<int, int>.identity()..addAll(generateMapIntInt(n));
}

/// Run the benchmark loop on various inputs to pollute type inference and JIT
/// caches.
void pollute() {
  // This iterable reads `sink` mid-loop, making it infeasible for the compiler
  // to move the write to `sink` out of the loop.
  sinkAll(UpTo(100).map((i) {
    if (i > 0 && sink != i - 1) throw StateError('sink');
    return i;
  }));

  // TODO(sra): Do we need to add anything here? There are a lot of benchmarks,
  // so that is probably sufficient to make the necessary places polymorphic.
}

/// Command-line arguments:
///
/// `--0`: Run benchmarks for empty iterables.
/// `--1`: Run benchmarks for singleton iterables.
/// `--2`: Run benchmarks for two-element iterables.
/// `--100`: Run benchmarks for 100-element iterables.
///
///    Default sizes are 1 and 100.
///
/// `--all`: Run all benchmark variants and sizes.
///
/// `foo`, `foo.bar`: a Selector.
///
///    Run benchmarks with name containing all the dot-separated words in the
///    selector, so `--Set.const` will run benchmark
///    `Iterators.const.Set.int.N`, and `--2.UpTo` will select
///    `Iterators.UpTo.2`.  Each selector is matched independently, and if
///    selectors are used, only benchmarks matching some selector are run.
///
void main(List<String> commandLineArguments) {
  final arguments = [...commandLineArguments];

  const allSizes = {0, 1, 2, 100};
  const defaultSizes = {1, 100};
  final allSizeWords = Set.unmodifiable(allSizes.map((size) => '$size'));

  final Set<int> sizes = {};
  final Set<String> selectors = {};

  if (arguments.remove('--0')) sizes.add(0);
  if (arguments.remove('--1')) sizes.add(1);
  if (arguments.remove('--2')) sizes.add(2);
  if (arguments.remove('--100')) sizes.add(100);

  if (arguments.remove('--all')) {
    sizes.addAll(allSizes);
  }

  selectors.addAll(arguments);

  if (sizes.isEmpty) sizes.addAll(defaultSizes);
  if (selectors.isEmpty) selectors.add('Iterators');

  List<Benchmark> makeBenchmarksForSize(int size) {
    return [
      // Simple
      BenchmarkNothing(size),
      BenchmarkUpTo(size),
      BenchmarkCodeUnits(size),
      Benchmark('UpTo', size, (n) => UpTo(n)),
      Benchmark('CodeUnits', size, (n) => generateString(n).codeUnits),
      Benchmark('Runes', size, (n) => generateString(n).runes),
      // ---
      BenchmarkListIntGrowable(size),
      BenchmarkListIntSystem1(size),
      BenchmarkListIntSystem2(size),
      Benchmark('List.int.growable', size,
          (n) => List<int>.of(UpTo(n), growable: true)),
      Benchmark('List.int.fixed', size,
          (n) => List<int>.of(UpTo(n), growable: false)),
      Benchmark('List.int.unmodifiable', size,
          (n) => List<int>.unmodifiable(UpTo(n))),
      // ---
      Benchmark('List.Hard.growable', size, generateThingList),
      // ---
      Benchmark('Set.int', size, (n) => Set<int>.of(UpTo(n))),
      Benchmark('const.Set.int', size, generateConstSetOfInt),
      // ---
      BenchmarkMapIntKeys(size),
      Benchmark('Map.int.keys', size, (n) => generateMapIntInt(n).keys),
      Benchmark('Map.int.values', size, (n) => generateMapIntInt(n).values),
      Benchmark('Map.int.entries', size, (n) => generateMapIntInt(n).entries),
      // ---
      Benchmark('Map.identity.int.keys', size,
          (n) => generateIdentityMapIntInt(n).keys),
      Benchmark('Map.identity.int.values', size,
          (n) => generateIdentityMapIntInt(n).values),
      Benchmark('Map.identity.int.entries', size,
          (n) => generateIdentityMapIntInt(n).entries),
      // ---
      Benchmark(
          'const.Map.int.keys', size, (n) => generateConstMapIntInt(n).keys),
      Benchmark('const.Map.int.values', size,
          (n) => generateConstMapIntInt(n).values),
      Benchmark('const.Map.int.entries', size,
          (n) => generateConstMapIntInt(n).entries),
      // ---
      Benchmark('Map.Hard.keys', size, (n) => generateThingMap(n).keys),
      Benchmark('Map.Hard.values', size, (n) => generateThingMap(n).values),
      // ---
      Benchmark('HashMap.int.keys', size,
          (n) => HashMap<int, int>.fromIterables(UpTo(n), UpTo(n)).keys),
      Benchmark('HashMap.int.values', size,
          (n) => HashMap<int, int>.fromIterables(UpTo(n), UpTo(n)).values),
      Benchmark('HashMap.int.entries', size,
          (n) => HashMap<int, int>.fromIterables(UpTo(n), UpTo(n)).entries),
      // ---
      Benchmark('HashMap.Hard.keys', size, (n) => generateThingHashMap(n).keys),
      Benchmark(
          'HashMap.Hard.values', size, (n) => generateThingHashMap(n).values),
    ];
  }

  final benchmarks = [
    BenchmarkConstMapIntKeys1(),
    BenchmarkConstMapIntKeys2(),
    BenchmarkConstMapIntKeys100(),
    BenchmarkConstMapIntValues1(),
    BenchmarkConstMapIntValues2(),
    BenchmarkConstMapIntValues100(),
    for (final size in allSizes) ...makeBenchmarksForSize(size),
  ];

  // Select benchmarks
  final unusedSelectors = {...selectors};
  for (final benchmark in benchmarks) {
    final nameWords = benchmark.name.split('.').toSet();
    for (final selector in selectors) {
      final selectorWords = selector.split('.').toSet();
      if (nameWords.containsAll(selectorWords)) {
        unusedSelectors.remove(selector);
        if (selectorWords.any(allSizeWords.contains) ||
            sizes.contains(benchmark.size)) {
          benchmark.selected = true;
        }
        // continue matching to remove other matching selectors.
      }
    }
  }
  if (unusedSelectors.isNotEmpty) {
    throw ArgumentError(unusedSelectors, 'selectors match no benchmark');
  }

  // Warmup all benchmarks to ensure JIT compilers see full polymorphism.
  for (var benchmark in benchmarks) {
    pollute();
    benchmark.setup();
  }

  // Warm up all the benchmarks, including the non-selected ones.
  for (int i = 0; i < 10; i++) {
    for (var benchmark in benchmarks) {
      pollute();
      final marker = Object();
      sink = marker;
      benchmark.warmup();
      if (benchmark.size > 0 && identical(sink, marker)) throw 'unexpected';
    }
  }

  for (var benchmark in benchmarks) {
    // `report` calls `setup`, but `setup` is idempotent.
    if (benchmark.selected) {
      benchmark.report();
    }
  }
}
