define(['dart_sdk'], function(dart_sdk) {
  'use strict';
  const core = dart_sdk.core;
  const dart = dart_sdk.dart;
  const dartx = dart_sdk.dartx;
  const BenchmarkBase$ = Object.create(null);
  let VoidTodynamic = () => (VoidTodynamic = dart.constFn(dart.definiteFunctionType(dart.dynamic, [])))();
  BenchmarkBase$.Expect = class Expect extends core.Object {
    static equals(expected, actual) {
      if (!dart.equals(expected, actual)) {
        dart.throw(dart.str`Values not equal: ${expected} vs ${actual}`);
      }
    }
    static listEquals(expected, actual) {
      if (expected[dartx.length] != actual[dartx.length]) {
        dart.throw(dart.str`Lists have different lengths: ${expected[dartx.length]} vs ${actual[dartx.length]}`);
      }
      for (let i = 0; i < dart.notNull(actual[dartx.length]); i++) {
        BenchmarkBase$.Expect.equals(expected[dartx.get](i), actual[dartx.get](i));
      }
    }
    fail(message) {
      dart.throw(message);
    }
  };
  dart.setSignature(BenchmarkBase$.Expect, {
    methods: () => ({fail: dart.definiteFunctionType(dart.dynamic, [dart.dynamic])}),
    statics: () => ({
      equals: dart.definiteFunctionType(dart.void, [dart.dynamic, dart.dynamic]),
      listEquals: dart.definiteFunctionType(dart.void, [core.List, core.List])
    }),
    names: ['equals', 'listEquals']
  });
  BenchmarkBase$.BenchmarkBase = class BenchmarkBase extends core.Object {
    new(name) {
      this.name = name;
    }
    run() {}
    warmup() {
      this.run();
    }
    exercise() {
      for (let i = 0; i < 10; i++) {
        this.run();
      }
    }
    setup() {}
    teardown() {}
    static measureFor(f, timeMinimum) {
      let time = 0;
      let iter = 0;
      let watch = new core.Stopwatch();
      watch.start();
      let elapsed = 0;
      while (dart.notNull(elapsed) < dart.notNull(timeMinimum)) {
        dart.dcall(f);
        elapsed = watch.elapsedMilliseconds;
        iter++;
      }
      return 1000.0 * dart.notNull(elapsed) / iter;
    }
    measure() {
      this.setup();
      BenchmarkBase$.BenchmarkBase.measureFor(dart.fn(() => {
        this.warmup();
      }, VoidTodynamic()), 100);
      let result = BenchmarkBase$.BenchmarkBase.measureFor(dart.fn(() => {
        this.exercise();
      }, VoidTodynamic()), 2000);
      this.teardown();
      return result;
    }
    report() {
      let score = this.measure();
      core.print(dart.str`${this.name}(RunTime): ${score} us.`);
    }
  };
  dart.setSignature(BenchmarkBase$.BenchmarkBase, {
    constructors: () => ({new: dart.definiteFunctionType(BenchmarkBase$.BenchmarkBase, [core.String])}),
    fields: () => ({name: core.String}),
    methods: () => ({
      run: dart.definiteFunctionType(dart.void, []),
      warmup: dart.definiteFunctionType(dart.void, []),
      exercise: dart.definiteFunctionType(dart.void, []),
      setup: dart.definiteFunctionType(dart.void, []),
      teardown: dart.definiteFunctionType(dart.void, []),
      measure: dart.definiteFunctionType(core.double, []),
      report: dart.definiteFunctionType(dart.void, [])
    }),
    statics: () => ({measureFor: dart.definiteFunctionType(core.double, [core.Function, core.int])}),
    names: ['measureFor']
  });
  // Exports:
  return {
    BenchmarkBase: BenchmarkBase$
  };
});
