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

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 = [
  Thing<Set<String>>.new,
  Thing<Set<Duration>>.new,
  Thing<Set<BigInt>>.new,
  Thing<Queue<String>>.new,
  Thing<Queue<Duration>>.new,
  Thing<Queue<BigInt>>.new,
  Thing<List<String>>.new,
  Thing<List<Duration>>.new,
  Thing<List<BigInt>>.new,
];

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, UpTo.new),
      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();
    }
  }
}
