Skip to content

Instantly share code, notes, and snippets.

@nicolasembleton
Last active July 28, 2021 12:57
Show Gist options
  • Save nicolasembleton/af8e8c09928c6911fe188e1a302c3bdf to your computer and use it in GitHub Desktop.
Save nicolasembleton/af8e8c09928c6911fe188e1a302c3bdf to your computer and use it in GitHub Desktop.

Revisions

  1. nicolasembleton revised this gist Jul 28, 2021. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions min_max_benchmark.dart
    Original file line number Diff line number Diff line change
    @@ -107,7 +107,7 @@ void main() {
    stopwatch.reset();
    }

    print('$element: ${benchmark.getStatsForKey(element).withPrecision(3)}');
    print('$element: ${benchmark.getStatsForKey(element)}');
    });

    print('**** DOUBLE suite ****');
    @@ -126,7 +126,7 @@ void main() {
    stopwatch.reset();
    }

    print('$element: ${benchmark.getStatsForKey(element).withPrecision(3)}');
    print('$element: ${benchmark.getStatsForKey(element)}');
    });
    // Unsurprisingly, sort is VERY slow. 20x forEach, which is itself very slow.
    // Not running the tests for sanity sake, but feel free to if you want to see.
  2. nicolasembleton revised this gist Jul 28, 2021. 1 changed file with 9 additions and 4 deletions.
    13 changes: 9 additions & 4 deletions min_max_benchmark.dart
    Original file line number Diff line number Diff line change
    @@ -1,10 +1,9 @@
    import 'dart:math';
    // import 'dart:convert';
    import 'package:stats/stats.dart';

    class Benchmark {
    Benchmark({this.UPPER_BOUND = 100000, this.withSlow = false}) {
    usingForLoopData = { for (var value in tests.keys) value : [] };
    reset();
    }

    int UPPER_BOUND;
    @@ -64,11 +63,16 @@ class Benchmark {
    }

    Stats getStatsForKey(key) {
    return Stats.fromData(usingForLoopData[key] as List<num>);
    return Stats.fromData(usingForLoopData[key] as List<num>).withPrecision(3);
    }

    Map<String, dynamic> getStats() {
    return { for (var value in tests.keys) value : Stats.fromData(usingForLoopData[value] as List<num>)};
    return { for (var key in tests.keys) key : getStatsForKey(key)};
    }

    // Reset counters
    void reset() {
    usingForLoopData = { for (var value in tests.keys) value : [] };
    }
    }

    @@ -108,6 +112,7 @@ void main() {

    print('**** DOUBLE suite ****');

    benchmark.reset();
    var listDouble = benchmark.generateList(type: 'double'); // List<double>
    print('List<double> created, elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();
  3. nicolasembleton revised this gist Jul 28, 2021. 1 changed file with 63 additions and 132 deletions.
    195 changes: 63 additions & 132 deletions min_max_benchmark.dart
    Original file line number Diff line number Diff line change
    @@ -3,27 +3,38 @@ import 'dart:math';
    import 'package:stats/stats.dart';

    class Benchmark {
    Benchmark({this.UPPER_BOUND = 100000}) {
    usingForLoopData = { for (var value in testsFunctions.keys) value : [] };
    Benchmark({this.UPPER_BOUND = 100000, this.withSlow = false}) {
    usingForLoopData = { for (var value in tests.keys) value : [] };
    }

    int UPPER_BOUND;
    bool withSlow;

    Map<String, Function> testsFunctions = {
    'smallestUsingForLoop': findMinUsingForLoop,
    'biggestUsingForLoop': findMaxUsingForLoop,
    'smallestUsingForLoopVar': findMinUsingForLoopVar,
    'biggestUsingForLoopVar': findMaxUsingForLoopVar,
    'smallestUsingForLoopGenericType': findMinUsingForLoopGenericType,
    'biggestUsingForLoopGenericType': findMaxUsingForLoopGenericType,
    'smallestUsingReverseForLoop': findMinUsingReverseForLoop,
    'biggestUsingReverseForLoop': findMaxUsingReverseForLoop,
    'smallestUsingReverseForLoopVar': findMinUsingReverseForLoopVar,
    'biggestUsingReverseForLoopVar': findMaxUsingReverseForLoopVar,
    'smallestUsingReverseForLoopGenericType': findMinUsingReverseForLoopGenericType,
    'biggestUsingReverseForLoopGenericType': findMaxUsingReverseForLoopGenericType,
    };

    Map<String, Function> slowTestsFunctions = {
    'smallestUsingForEachLoop': findMinUsingForEachLoop,
    'biggestUsingForEachLoop': findMaxUsingForEachLoop,
    'smallestUsingReduce': findMinUsingReduce,
    'biggestUsingReduce': findMaxUsingReduce,
    'smallestUsingFold': findMinUsingFold,
    'biggestUsingFold': findMaxUsingFold,
    };

    Map<String, Function> get tests {
    if(withSlow) return {}..addAll(testsFunctions)..addAll(slowTestsFunctions);
    return testsFunctions;
    }

    late Map<String, List<double>> usingForLoopData;

    List<T> generateList<T extends num>({String type = 'int'}) {
    @@ -57,7 +68,7 @@ class Benchmark {
    }

    Map<String, dynamic> getStats() {
    return { for (var value in testsFunctions.keys) value : Stats.fromData(usingForLoopData[value] as List<num>)};
    return { for (var value in tests.keys) value : Stats.fromData(usingForLoopData[value] as List<num>)};
    }
    }

    @@ -69,23 +80,24 @@ void main() {
    // rng.nextInt(429496729);
    // Biggest possible number: 4294967296
    var UPPER_BOUND = 10000000;
    var BENCHMARKING_ROUNDS = 1000;
    var BENCHMARKING_ROUNDS = 250;

    var benchmark = Benchmark(UPPER_BOUND: UPPER_BOUND);
    var benchmark = Benchmark(UPPER_BOUND: UPPER_BOUND, withSlow: false);
    var stopwatch = Stopwatch()..start();
    var list = benchmark.generateList(); // List<int>
    print('List<int> created, elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset(); // reset the watch

    print('UPPER_BOUND: $UPPER_BOUND');
    print('BENCHMARKING_ROUNDS: $BENCHMARKING_ROUNDS');

    print('**** INT suite ****');

    benchmark.testsFunctions.keys.forEach((element) {
    var listInt = benchmark.generateList(); // List<int>
    print('List<int> created, elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset(); // reset the watch

    benchmark.tests.keys.forEach((element) {
    // Run tests
    for(var i=0;i<BENCHMARKING_ROUNDS;i++) {
    benchmark.testsFunctions[element]!.call(list);
    benchmark.tests[element]!.call(listInt);
    var elapsed = stopwatch.elapsedMilliseconds/1000;
    benchmark.addMeasurementToList(testKey: element, elapsed: elapsed, andPrint: false);
    stopwatch.reset();
    @@ -94,6 +106,23 @@ void main() {
    print('$element: ${benchmark.getStatsForKey(element).withPrecision(3)}');
    });

    print('**** DOUBLE suite ****');

    var listDouble = benchmark.generateList(type: 'double'); // List<double>
    print('List<double> created, elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    benchmark.tests.keys.forEach((element) {
    // Run tests
    for(var i=0;i<BENCHMARKING_ROUNDS;i++) {
    benchmark.tests[element]!.call(listDouble);
    var elapsed = stopwatch.elapsedMilliseconds/1000;
    benchmark.addMeasurementToList(testKey: element, elapsed: elapsed, andPrint: false);
    stopwatch.reset();
    }

    print('$element: ${benchmark.getStatsForKey(element).withPrecision(3)}');
    });
    // Unsurprisingly, sort is VERY slow. 20x forEach, which is itself very slow.
    // Not running the tests for sanity sake, but feel free to if you want to see.
    //List el2_min = List.from(el);
    @@ -108,83 +137,9 @@ void main() {
    //int biggestUsingSort = findMaxUsingSort(el2_max);
    //print('Find max using sort ($biggestUsingSort), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    //stopwatch.reset();

    // int smallestUsingForEachLoop = findMinUsingForEachLoop(el);
    // print('Find min using forEach loops ($smallestUsingForEachLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    // stopwatch.reset();
    //
    // int biggestUsingForEachLoop = findMaxUsingForEachLoop(el);
    // print('Find max using forEach loops ($biggestUsingForEachLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    // stopwatch.reset();
    //
    // int smallestUsingReduce = findMinUsingReduce(el);
    // print('Find min using reduce ($smallestUsingReduce), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    // stopwatch.reset();
    //
    // int biggestUsingReduce = findMaxUsingReduce(el);
    // print('Find max using reduce ($biggestUsingReduce), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    // stopwatch.reset();
    //
    // int smallestUsingFold = findMinUsingFold(el);
    // print('Find min using fold ($smallestUsingFold), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    // stopwatch.reset();
    //
    // int biggestUsingFold = findMaxUsingFold(el);
    // print('Find max using fold ($biggestUsingFold), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    // stopwatch.reset();

    // print('**** DOUBLE suite ****');
    //
    // List<double> eld = [];
    // for(int i=0; i<UPPER_BOUND;i++) {
    // eld.add(rng.nextDouble() * UPPER_BOUND);
    // }
    //
    // print('List<double> created, elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    // stopwatch.reset(); // reset the watch
    //
    // double smallestDoubleUsingForLoopGenericType = findMinUsingForLoopGenericType(eld);
    // print('Find min using for loops with Generic Type ($smallestDoubleUsingForLoopGenericType), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    // stopwatch.reset();
    //
    // double biggestDoubleUsingForLoopGenericType = findMaxUsingForLoopGenericType(eld);
    // print('Find max using for loops with Generic Type ($biggestDoubleUsingForLoopGenericType), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    // stopwatch.reset();
    //
    // double smallestDoubleUsingReverseForLoopGenericType = findMinUsingReverseForLoopGenericType(eld);
    // print('Find min using reverse for loops with Generic Type ($smallestDoubleUsingReverseForLoopGenericType), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    // stopwatch.reset();
    //
    // double biggestDoubleUsingReverseForLoopGenericType = findMaxUsingReverseForLoopGenericType(eld);
    // print('Find max using reverse for loops with Generic Type ($biggestDoubleUsingReverseForLoopGenericType), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    // stopwatch.reset();
    }

    int findMinUsingForLoop(List el) {
    int smallest = el.first;

    for (var i = 0; i < el.length; i++) {
    if (el[i] < smallest) {
    smallest = el[i];
    }
    }

    return smallest;
    }

    int findMaxUsingForLoop(List el) {
    int biggest = el.first;

    for (var i = 0; i < el.length; i++) {
    if (el[i] > biggest) {
    biggest = el[i];
    }
    }

    return biggest;
    }

    int findMinUsingForLoopVar(List el) {
    num findMinUsingForLoopVar(List el) {
    var smallest = el.first;

    for (var i = 0; i < el.length; i++) {
    @@ -196,7 +151,7 @@ int findMinUsingForLoopVar(List el) {
    return smallest;
    }

    int findMaxUsingForLoopVar(List el) {
    num findMaxUsingForLoopVar(List el) {
    var biggest = el.first;

    for (var i = 0; i < el.length; i++) {
    @@ -208,7 +163,7 @@ int findMaxUsingForLoopVar(List el) {
    return biggest;
    }

    T findMinUsingForLoopGenericType<T extends int, double>(List el) {
    T findMinUsingForLoopGenericType<T extends num>(List el) {
    var smallest = el.first as T;

    for (var i = 0; i < el.length; i++) {
    @@ -220,7 +175,7 @@ T findMinUsingForLoopGenericType<T extends int, double>(List el) {
    return smallest;
    }

    T findMaxUsingForLoopGenericType<T extends int, double>(List el) {
    T findMaxUsingForLoopGenericType<T extends num>(List el) {
    var biggest = el.first;

    for (var i = 0; i < el.length; i++) {
    @@ -232,31 +187,7 @@ T findMaxUsingForLoopGenericType<T extends int, double>(List el) {
    return biggest;
    }

    int findMinUsingReverseForLoop(List el) {
    int smallest = el.first;

    for (var i = el.length-1; i >= 0; i--) {
    if (el[i] < smallest) {
    smallest = el[i];
    }
    }

    return smallest;
    }

    int findMaxUsingReverseForLoop(List el) {
    int biggest = el.first;

    for (var i = el.length-1; i >= 0; i--) {
    if (el[i] > biggest) {
    biggest = el[i];
    }
    }

    return biggest;
    }

    int findMinUsingReverseForLoopVar(List el) {
    num findMinUsingReverseForLoopVar(List el) {
    var smallest = el.first;

    for (var i = el.length-1; i >= 0; i--) {
    @@ -268,7 +199,7 @@ int findMinUsingReverseForLoopVar(List el) {
    return smallest;
    }

    int findMaxUsingReverseForLoopVar(List el) {
    num findMaxUsingReverseForLoopVar(List el) {
    var biggest = el.first;

    for (var i = el.length-1; i >= 0; i--) {
    @@ -280,7 +211,7 @@ int findMaxUsingReverseForLoopVar(List el) {
    return biggest;
    }

    T findMinUsingReverseForLoopGenericType<T extends int, double>(List el) {
    T findMinUsingReverseForLoopGenericType<T extends num>(List el) {
    var smallest = el.first as T;

    for (var i = el.length-1; i >= 0; i--) {
    @@ -292,7 +223,7 @@ T findMinUsingReverseForLoopGenericType<T extends int, double>(List el) {
    return smallest;
    }

    T findMaxUsingReverseForLoopGenericType<T extends int, double>(List el) {
    T findMaxUsingReverseForLoopGenericType<T extends num>(List el) {
    var biggest = el.first as T;

    for (var i = el.length-1; i >= 0; i--) {
    @@ -304,17 +235,17 @@ T findMaxUsingReverseForLoopGenericType<T extends int, double>(List el) {
    return biggest;
    }

    int findMinUsingSort(List el) {
    num findMinUsingSort(List el) {
    el.sort();
    return el.first;
    }

    int findMaxUsingSort(List el) {
    num findMaxUsingSort(List el) {
    el.sort();
    return el.last;
    }

    int findMinUsingForEachLoop(List el) {
    num findMinUsingForEachLoop(List el) {
    var smallest = el.first;

    el.forEach((val) => {
    @@ -324,7 +255,7 @@ int findMinUsingForEachLoop(List el) {
    return smallest;
    }

    int findMaxUsingForEachLoop(List el) {
    num findMaxUsingForEachLoop(List el) {
    var biggest = el.first;

    el.forEach((val) => {
    @@ -334,18 +265,18 @@ int findMaxUsingForEachLoop(List el) {
    return biggest;
    }

    int findMinUsingFold(List<int> el) {
    return el.fold(el.first, min);
    num findMinUsingFold(List el) {
    return (el as List<num>).fold(el.first, min);
    }

    int findMaxUsingFold(List<int> el) {
    return el.fold(el.first, max);
    num findMaxUsingFold(List el) {
    return (el as List<num>).fold(el.first, max);
    }

    int findMinUsingReduce(List<int> el) {
    return el.reduce(min);
    num findMinUsingReduce(List el) {
    return (el as List<num>).reduce(min);
    }

    int findMaxUsingReduce(List<int> el) {
    return el.reduce(max);
    num findMaxUsingReduce(List el) {
    return (el as List<num>).reduce(max);
    }
  4. nicolasembleton revised this gist Jul 28, 2021. 1 changed file with 106 additions and 83 deletions.
    189 changes: 106 additions & 83 deletions min_max_benchmark.dart
    Original file line number Diff line number Diff line change
    @@ -1,75 +1,98 @@
    import 'dart:math';
    // import 'dart:convert';
    import 'package:stats/stats.dart';

    void main() {
    print('Benchmarking min / max finders');

    Random rng = new Random();
    // Good number for testing: 10000000
    // Reasonable number for good quality output: 388805700
    // rng.nextInt(429496729);
    // Biggest possible number: 4294967296
    int UPPER_BOUND = 10000000;
    print('UPPER_BOUND: $UPPER_BOUND');

    var stopwatch = Stopwatch()..start();

    print('**** INT suite ****');

    List<int> el = [];
    for(int i=0; i<UPPER_BOUND;i++) {
    el.add(rng.nextInt(UPPER_BOUND));
    class Benchmark {
    Benchmark({this.UPPER_BOUND = 100000}) {
    usingForLoopData = { for (var value in testsFunctions.keys) value : [] };
    }

    print('List<int> created, elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset(); // reset the watch

    int smallestUsingForLoop = findMinUsingForLoop(el);
    print('Find min using for loops with typed control value ($smallestUsingForLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();
    int UPPER_BOUND;

    Map<String, Function> testsFunctions = {
    'smallestUsingForLoop': findMinUsingForLoop,
    'biggestUsingForLoop': findMaxUsingForLoop,
    'smallestUsingForLoopVar': findMinUsingForLoopVar,
    'biggestUsingForLoopVar': findMaxUsingForLoopVar,
    'smallestUsingForLoopGenericType': findMinUsingForLoopGenericType,
    'biggestUsingForLoopGenericType': findMaxUsingForLoopGenericType,
    'smallestUsingReverseForLoop': findMinUsingReverseForLoop,
    'biggestUsingReverseForLoop': findMaxUsingReverseForLoop,
    'smallestUsingReverseForLoopVar': findMinUsingReverseForLoopVar,
    'biggestUsingReverseForLoopVar': findMaxUsingReverseForLoopVar,
    'smallestUsingReverseForLoopGenericType': findMinUsingReverseForLoopGenericType,
    'biggestUsingReverseForLoopGenericType': findMaxUsingReverseForLoopGenericType,
    };

    late Map<String, List<double>> usingForLoopData;

    List<T> generateList<T extends num>({String type = 'int'}) {
    var el = <T>[];

    var rng = Random();

    for(var i=0; i<UPPER_BOUND;i++) {
    if(type == 'double') {
    // double
    el.add((rng.nextDouble() * UPPER_BOUND) as T);
    } else {
    // int
    el.add(rng.nextInt(UPPER_BOUND) as T);
    }
    }
    return el;
    }

    int biggestUsingForLoop = findMaxUsingForLoop(el);
    print('Find max using for loops with typed control value ($biggestUsingForLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();
    void addMeasurementToList({required String testKey, required double elapsed, bool andPrint = false}) {
    assert(usingForLoopData.containsKey(testKey), true);
    usingForLoopData[testKey]!.add(elapsed);

    int smallestUsingForLoopVar = findMinUsingForLoopVar(el);
    print('Find min using for loops with var control value ($smallestUsingForLoopVar, elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();
    if(andPrint) {
    print('$testKey, elapsed: $elapsed');
    }
    }

    int biggestUsingForLoopVar = findMaxUsingForLoopVar(el);
    print('Find max using for loops with var control value ($biggestUsingForLoopVar), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();
    Stats getStatsForKey(key) {
    return Stats.fromData(usingForLoopData[key] as List<num>);
    }

    int smallestUsingForLoopGenericType = findMinUsingForLoopGenericType(el);
    print('Find min using for loops with Generic Type ($smallestUsingForLoopGenericType), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();
    Map<String, dynamic> getStats() {
    return { for (var value in testsFunctions.keys) value : Stats.fromData(usingForLoopData[value] as List<num>)};
    }
    }

    int biggestUsingForLoopGenericType = findMaxUsingForLoopGenericType(el);
    print('Find max using for loops with Generic Type ($biggestUsingForLoopGenericType), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();
    void main() {
    print('Benchmarking min / max finders');

    int smallestUsingReverseForLoop = findMinUsingReverseForLoop(el);
    print('Find min using reverse for loops with typed control value ($smallestUsingReverseForLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();
    // Good number for testing: 10000000
    // Reasonable number for good quality output: 388805700
    // rng.nextInt(429496729);
    // Biggest possible number: 4294967296
    var UPPER_BOUND = 10000000;
    var BENCHMARKING_ROUNDS = 1000;

    int biggestUsingReverseForLoop = findMaxUsingReverseForLoop(el);
    print('Find max using reverse for loops with typed control value ($biggestUsingReverseForLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();
    var benchmark = Benchmark(UPPER_BOUND: UPPER_BOUND);
    var stopwatch = Stopwatch()..start();
    var list = benchmark.generateList(); // List<int>
    print('List<int> created, elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset(); // reset the watch

    int smallestUsingReverseForLoopVar = findMinUsingReverseForLoopVar(el);
    print('Find min using reverse for loops with var control value ($smallestUsingReverseForLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();
    print('UPPER_BOUND: $UPPER_BOUND');
    print('BENCHMARKING_ROUNDS: $BENCHMARKING_ROUNDS');

    int biggestUsingReverseForLoopVar = findMaxUsingReverseForLoopVar(el);
    print('Find max using reverse for loops with var control value ($biggestUsingReverseForLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();
    print('**** INT suite ****');

    int smallestUsingReverseForLoopGenericType = findMinUsingReverseForLoopGenericType(el);
    print('Find min using reverse for loops with Generic Type ($smallestUsingReverseForLoopGenericType), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();
    benchmark.testsFunctions.keys.forEach((element) {
    // Run tests
    for(var i=0;i<BENCHMARKING_ROUNDS;i++) {
    benchmark.testsFunctions[element]!.call(list);
    var elapsed = stopwatch.elapsedMilliseconds/1000;
    benchmark.addMeasurementToList(testKey: element, elapsed: elapsed, andPrint: false);
    stopwatch.reset();
    }

    int biggestUsingReverseForLoopGenericType = findMaxUsingReverseForLoopGenericType(el);
    print('Find max using reverse for loops with Generic Type ($biggestUsingReverseForLoopGenericType), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();
    print('$element: ${benchmark.getStatsForKey(element).withPrecision(3)}');
    });

    // Unsurprisingly, sort is VERY slow. 20x forEach, which is itself very slow.
    // Not running the tests for sanity sake, but feel free to if you want to see.
    @@ -86,29 +109,29 @@ void main() {
    //print('Find max using sort ($biggestUsingSort), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    //stopwatch.reset();

    int smallestUsingForEachLoop = findMinUsingForEachLoop(el);
    print('Find min using forEach loops ($smallestUsingForEachLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    int biggestUsingForEachLoop = findMaxUsingForEachLoop(el);
    print('Find max using forEach loops ($biggestUsingForEachLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    int smallestUsingReduce = findMinUsingReduce(el);
    print('Find min using reduce ($smallestUsingReduce), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    int biggestUsingReduce = findMaxUsingReduce(el);
    print('Find max using reduce ($biggestUsingReduce), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    int smallestUsingFold = findMinUsingFold(el);
    print('Find min using fold ($smallestUsingFold), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    int biggestUsingFold = findMaxUsingFold(el);
    print('Find max using fold ($biggestUsingFold), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();
    // int smallestUsingForEachLoop = findMinUsingForEachLoop(el);
    // print('Find min using forEach loops ($smallestUsingForEachLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    // stopwatch.reset();
    //
    // int biggestUsingForEachLoop = findMaxUsingForEachLoop(el);
    // print('Find max using forEach loops ($biggestUsingForEachLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    // stopwatch.reset();
    //
    // int smallestUsingReduce = findMinUsingReduce(el);
    // print('Find min using reduce ($smallestUsingReduce), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    // stopwatch.reset();
    //
    // int biggestUsingReduce = findMaxUsingReduce(el);
    // print('Find max using reduce ($biggestUsingReduce), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    // stopwatch.reset();
    //
    // int smallestUsingFold = findMinUsingFold(el);
    // print('Find min using fold ($smallestUsingFold), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    // stopwatch.reset();
    //
    // int biggestUsingFold = findMaxUsingFold(el);
    // print('Find max using fold ($biggestUsingFold), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    // stopwatch.reset();

    // print('**** DOUBLE suite ****');
    //
    @@ -186,7 +209,7 @@ int findMaxUsingForLoopVar(List el) {
    }

    T findMinUsingForLoopGenericType<T extends int, double>(List el) {
    T smallest = el.first as T;
    var smallest = el.first as T;

    for (var i = 0; i < el.length; i++) {
    if (el[i] < smallest) {
    @@ -258,7 +281,7 @@ int findMaxUsingReverseForLoopVar(List el) {
    }

    T findMinUsingReverseForLoopGenericType<T extends int, double>(List el) {
    T smallest = el.first as T;
    var smallest = el.first as T;

    for (var i = el.length-1; i >= 0; i--) {
    if (el[i] < smallest) {
    @@ -270,7 +293,7 @@ T findMinUsingReverseForLoopGenericType<T extends int, double>(List el) {
    }

    T findMaxUsingReverseForLoopGenericType<T extends int, double>(List el) {
    T biggest = el.first as T;
    var biggest = el.first as T;

    for (var i = el.length-1; i >= 0; i--) {
    if (el[i] > biggest) {
  5. nicolasembleton revised this gist Jul 27, 2021. 1 changed file with 173 additions and 18 deletions.
    191 changes: 173 additions & 18 deletions min_max_benchmark.dart
    Original file line number Diff line number Diff line change
    @@ -1,41 +1,74 @@
    import 'dart:math';
    import 'dart:core';

    void main() {
    print('Benchmarking min / max finders');

    Random rng = new Random();
    // Good number for testing: 10000000
    // Good number for testing: 10000000
    // Reasonable number for good quality output: 388805700
    // rng.nextInt(429496729);
    // Biggest possible number: 4294967296
    int UPPER_BOUND = 100000000;
    int UPPER_BOUND = 10000000;
    print('UPPER_BOUND: $UPPER_BOUND');

    var stopwatch = Stopwatch()..start();

    print('**** INT suite ****');

    List<int> el = [];
    for(int i=0; i<UPPER_BOUND;i++) {
    el.add(rng.nextInt(UPPER_BOUND));
    }

    print('List created, elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    print('List<int> created, elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset(); // reset the watch

    int smallestUsingForLoop = findMinUsingForLoop(el);
    print('Find min using for loops ($smallestUsingForLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    print('Find min using for loops with typed control value ($smallestUsingForLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    int biggestUsingForLoop = findMaxUsingForLoop(el);
    print('Find max using for loops ($biggestUsingForLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();
    print('Find max using for loops with typed control value ($biggestUsingForLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    int smallestUsingForLoopVar = findMinUsingForLoopVar(el);
    print('Find min using for loops with var control value ($smallestUsingForLoopVar, elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    int biggestUsingForLoopVar = findMaxUsingForLoopVar(el);
    print('Find max using for loops with var control value ($biggestUsingForLoopVar), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    int smallestUsingForLoopGenericType = findMinUsingForLoopGenericType(el);
    print('Find min using for loops with Generic Type ($smallestUsingForLoopGenericType), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    int biggestUsingForLoopGenericType = findMaxUsingForLoopGenericType(el);
    print('Find max using for loops with Generic Type ($biggestUsingForLoopGenericType), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    int smallestUsingReverseForLoop = findMinUsingReverseForLoop(el);
    print('Find min using reverse for loops ($smallestUsingReverseForLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    print('Find min using reverse for loops with typed control value ($smallestUsingReverseForLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    int biggestUsingReverseForLoop = findMaxUsingReverseForLoop(el);
    print('Find max using reverse for loops ($biggestUsingReverseForLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    print('Find max using reverse for loops with typed control value ($biggestUsingReverseForLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    int smallestUsingReverseForLoopVar = findMinUsingReverseForLoopVar(el);
    print('Find min using reverse for loops with var control value ($smallestUsingReverseForLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    int biggestUsingReverseForLoopVar = findMaxUsingReverseForLoopVar(el);
    print('Find max using reverse for loops with var control value ($biggestUsingReverseForLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    int smallestUsingReverseForLoopGenericType = findMinUsingReverseForLoopGenericType(el);
    print('Find min using reverse for loops with Generic Type ($smallestUsingReverseForLoopGenericType), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    int biggestUsingReverseForLoopGenericType = findMaxUsingReverseForLoopGenericType(el);
    print('Find max using reverse for loops with Generic Type ($biggestUsingReverseForLoopGenericType), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    // Unsurprisingly, sort is VERY slow. 20x forEach, which is itself very slow.
    @@ -76,11 +109,37 @@ void main() {
    int biggestUsingFold = findMaxUsingFold(el);
    print('Find max using fold ($biggestUsingFold), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    // print('**** DOUBLE suite ****');
    //
    // List<double> eld = [];
    // for(int i=0; i<UPPER_BOUND;i++) {
    // eld.add(rng.nextDouble() * UPPER_BOUND);
    // }
    //
    // print('List<double> created, elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    // stopwatch.reset(); // reset the watch
    //
    // double smallestDoubleUsingForLoopGenericType = findMinUsingForLoopGenericType(eld);
    // print('Find min using for loops with Generic Type ($smallestDoubleUsingForLoopGenericType), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    // stopwatch.reset();
    //
    // double biggestDoubleUsingForLoopGenericType = findMaxUsingForLoopGenericType(eld);
    // print('Find max using for loops with Generic Type ($biggestDoubleUsingForLoopGenericType), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    // stopwatch.reset();
    //
    // double smallestDoubleUsingReverseForLoopGenericType = findMinUsingReverseForLoopGenericType(eld);
    // print('Find min using reverse for loops with Generic Type ($smallestDoubleUsingReverseForLoopGenericType), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    // stopwatch.reset();
    //
    // double biggestDoubleUsingReverseForLoopGenericType = findMaxUsingReverseForLoopGenericType(eld);
    // print('Find max using reverse for loops with Generic Type ($biggestDoubleUsingReverseForLoopGenericType), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    // stopwatch.reset();
    }

    int findMinUsingForLoop(List el) {
    var smallest = el[0];
    int smallest = el.first;

    for (var i = 0; i < el.length; i++) {
    if (el[i] < smallest) {
    smallest = el[i];
    @@ -91,7 +150,55 @@ int findMinUsingForLoop(List el) {
    }

    int findMaxUsingForLoop(List el) {
    var biggest = el[0];
    int biggest = el.first;

    for (var i = 0; i < el.length; i++) {
    if (el[i] > biggest) {
    biggest = el[i];
    }
    }

    return biggest;
    }

    int findMinUsingForLoopVar(List el) {
    var smallest = el.first;

    for (var i = 0; i < el.length; i++) {
    if (el[i] < smallest) {
    smallest = el[i];
    }
    }

    return smallest;
    }

    int findMaxUsingForLoopVar(List el) {
    var biggest = el.first;

    for (var i = 0; i < el.length; i++) {
    if (el[i] > biggest) {
    biggest = el[i];
    }
    }

    return biggest;
    }

    T findMinUsingForLoopGenericType<T extends int, double>(List el) {
    T smallest = el.first as T;

    for (var i = 0; i < el.length; i++) {
    if (el[i] < smallest) {
    smallest = el[i];
    }
    }

    return smallest;
    }

    T findMaxUsingForLoopGenericType<T extends int, double>(List el) {
    var biggest = el.first;

    for (var i = 0; i < el.length; i++) {
    if (el[i] > biggest) {
    @@ -103,7 +210,7 @@ int findMaxUsingForLoop(List el) {
    }

    int findMinUsingReverseForLoop(List el) {
    var smallest = el[0];
    int smallest = el.first;

    for (var i = el.length-1; i >= 0; i--) {
    if (el[i] < smallest) {
    @@ -115,7 +222,55 @@ int findMinUsingReverseForLoop(List el) {
    }

    int findMaxUsingReverseForLoop(List el) {
    var biggest = el[0];
    int biggest = el.first;

    for (var i = el.length-1; i >= 0; i--) {
    if (el[i] > biggest) {
    biggest = el[i];
    }
    }

    return biggest;
    }

    int findMinUsingReverseForLoopVar(List el) {
    var smallest = el.first;

    for (var i = el.length-1; i >= 0; i--) {
    if (el[i] < smallest) {
    smallest = el[i];
    }
    }

    return smallest;
    }

    int findMaxUsingReverseForLoopVar(List el) {
    var biggest = el.first;

    for (var i = el.length-1; i >= 0; i--) {
    if (el[i] > biggest) {
    biggest = el[i];
    }
    }

    return biggest;
    }

    T findMinUsingReverseForLoopGenericType<T extends int, double>(List el) {
    T smallest = el.first as T;

    for (var i = el.length-1; i >= 0; i--) {
    if (el[i] < smallest) {
    smallest = el[i];
    }
    }

    return smallest;
    }

    T findMaxUsingReverseForLoopGenericType<T extends int, double>(List el) {
    T biggest = el.first as T;

    for (var i = el.length-1; i >= 0; i--) {
    if (el[i] > biggest) {
    @@ -137,7 +292,7 @@ int findMaxUsingSort(List el) {
    }

    int findMinUsingForEachLoop(List el) {
    var smallest = el[0];
    var smallest = el.first;

    el.forEach((val) => {
    if(val < smallest) {smallest = val}
    @@ -147,7 +302,7 @@ int findMinUsingForEachLoop(List el) {
    }

    int findMaxUsingForEachLoop(List el) {
    var biggest = el[0];
    var biggest = el.first;

    el.forEach((val) => {
    if(val > biggest) {biggest = val}
    @@ -157,11 +312,11 @@ int findMaxUsingForEachLoop(List el) {
    }

    int findMinUsingFold(List<int> el) {
    return el.fold(el[0], min);
    return el.fold(el.first, min);
    }

    int findMaxUsingFold(List<int> el) {
    return el.fold(el[0], max);
    return el.fold(el.first, max);
    }

    int findMinUsingReduce(List<int> el) {
  6. nicolasembleton created this gist Jul 27, 2021.
    173 changes: 173 additions & 0 deletions min_max_benchmark.dart
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,173 @@
    import 'dart:math';
    import 'dart:core';

    void main() {
    print('Benchmarking min / max finders');

    Random rng = new Random();
    // Good number for testing: 10000000
    // Reasonable number for good quality output: 388805700
    // rng.nextInt(429496729);
    // Biggest possible number: 4294967296
    int UPPER_BOUND = 100000000;
    print('UPPER_BOUND: $UPPER_BOUND');

    var stopwatch = Stopwatch()..start();

    List<int> el = [];
    for(int i=0; i<UPPER_BOUND;i++) {
    el.add(rng.nextInt(UPPER_BOUND));
    }

    print('List created, elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset(); // reset the watch

    int smallestUsingForLoop = findMinUsingForLoop(el);
    print('Find min using for loops ($smallestUsingForLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    int biggestUsingForLoop = findMaxUsingForLoop(el);
    print('Find max using for loops ($biggestUsingForLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    int smallestUsingReverseForLoop = findMinUsingReverseForLoop(el);
    print('Find min using reverse for loops ($smallestUsingReverseForLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    int biggestUsingReverseForLoop = findMaxUsingReverseForLoop(el);
    print('Find max using reverse for loops ($biggestUsingReverseForLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    // Unsurprisingly, sort is VERY slow. 20x forEach, which is itself very slow.
    // Not running the tests for sanity sake, but feel free to if you want to see.
    //List el2_min = List.from(el);
    //List el2_max = List.from(el);
    //print('Cloning the list for modifying methods: elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    //stopwatch.reset();

    //int smallestUsingSort = findMinUsingSort(el2_min);
    //print('Find min using sort ($smallestUsingSort), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    //stopwatch.reset();

    //int biggestUsingSort = findMaxUsingSort(el2_max);
    //print('Find max using sort ($biggestUsingSort), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    //stopwatch.reset();

    int smallestUsingForEachLoop = findMinUsingForEachLoop(el);
    print('Find min using forEach loops ($smallestUsingForEachLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    int biggestUsingForEachLoop = findMaxUsingForEachLoop(el);
    print('Find max using forEach loops ($biggestUsingForEachLoop), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    int smallestUsingReduce = findMinUsingReduce(el);
    print('Find min using reduce ($smallestUsingReduce), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    int biggestUsingReduce = findMaxUsingReduce(el);
    print('Find max using reduce ($biggestUsingReduce), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    int smallestUsingFold = findMinUsingFold(el);
    print('Find min using fold ($smallestUsingFold), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();

    int biggestUsingFold = findMaxUsingFold(el);
    print('Find max using fold ($biggestUsingFold), elapsed: ${stopwatch.elapsedMilliseconds/1000}');
    stopwatch.reset();
    }

    int findMinUsingForLoop(List el) {
    var smallest = el[0];

    for (var i = 0; i < el.length; i++) {
    if (el[i] < smallest) {
    smallest = el[i];
    }
    }

    return smallest;
    }

    int findMaxUsingForLoop(List el) {
    var biggest = el[0];

    for (var i = 0; i < el.length; i++) {
    if (el[i] > biggest) {
    biggest = el[i];
    }
    }

    return biggest;
    }

    int findMinUsingReverseForLoop(List el) {
    var smallest = el[0];

    for (var i = el.length-1; i >= 0; i--) {
    if (el[i] < smallest) {
    smallest = el[i];
    }
    }

    return smallest;
    }

    int findMaxUsingReverseForLoop(List el) {
    var biggest = el[0];

    for (var i = el.length-1; i >= 0; i--) {
    if (el[i] > biggest) {
    biggest = el[i];
    }
    }

    return biggest;
    }

    int findMinUsingSort(List el) {
    el.sort();
    return el.first;
    }

    int findMaxUsingSort(List el) {
    el.sort();
    return el.last;
    }

    int findMinUsingForEachLoop(List el) {
    var smallest = el[0];

    el.forEach((val) => {
    if(val < smallest) {smallest = val}
    });

    return smallest;
    }

    int findMaxUsingForEachLoop(List el) {
    var biggest = el[0];

    el.forEach((val) => {
    if(val > biggest) {biggest = val}
    });

    return biggest;
    }

    int findMinUsingFold(List<int> el) {
    return el.fold(el[0], min);
    }

    int findMaxUsingFold(List<int> el) {
    return el.fold(el[0], max);
    }

    int findMinUsingReduce(List<int> el) {
    return el.reduce(min);
    }

    int findMaxUsingReduce(List<int> el) {
    return el.reduce(max);
    }