| Index: packages/observe/benchmark/index.dart
|
| diff --git a/packages/observe/benchmark/index.dart b/packages/observe/benchmark/index.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..781e0aad47a09a11e8de03ec25cc603e54469576
|
| --- /dev/null
|
| +++ b/packages/observe/benchmark/index.dart
|
| @@ -0,0 +1,168 @@
|
| +// Copyright (c) 2013, 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.
|
| +library observe.test.benchmark.index;
|
| +
|
| +import 'dart:async';
|
| +import 'dart:html';
|
| +import 'package:benchmark_harness/benchmark_harness.dart';
|
| +import 'package:chart/chart.dart';
|
| +import 'package:observe/mirrors_used.dart'; // Makes output smaller.
|
| +import 'package:smoke/mirrors.dart';
|
| +import 'object_benchmark.dart';
|
| +import 'setup_object_benchmark.dart';
|
| +import 'observable_list_benchmark.dart';
|
| +import 'setup_observable_list_benchmark.dart';
|
| +import 'path_benchmark.dart';
|
| +import 'setup_path_benchmark.dart';
|
| +
|
| +/// Benchmark names to factory functions.
|
| +typedef BenchmarkBase BenchmarkFactory(
|
| + int objectCount, int mutationCount, String config);
|
| +final Map<String, BenchmarkFactory> benchmarkFactories = {
|
| + 'ObjectBenchmark': (int o, int m, String c) => new ObjectBenchmark(o, m, c),
|
| + 'SetupObjectBenchmark':
|
| + (int o, int m, String c) => new SetupObjectBenchmark(o, c),
|
| + 'ObservableListBenchmark':
|
| + (int o, int m, String c) => new ObservableListBenchmark(o, m, c),
|
| + 'SetupObservableListBenchmark':
|
| + (int o, int m, String c) => new SetupObservableListBenchmark(o, c),
|
| + 'PathBenchmark': (int o, int m, String c) => new PathBenchmark(o, m, c),
|
| + 'SetupPathBenchmark':
|
| + (int o, int m, String c) => new SetupPathBenchmark(o, c),
|
| +};
|
| +
|
| +/// Benchmark names to possible configs.
|
| +final Map<String, List<String>> benchmarkConfigs = {
|
| + 'ObjectBenchmark': [],
|
| + 'SetupObjectBenchmark': [],
|
| + 'ObservableListBenchmark': ['splice', 'update', 'push/pop', 'shift/unshift'],
|
| + 'SetupObservableListBenchmark': [],
|
| + 'PathBenchmark': ['leaf', 'root'],
|
| + 'SetupPathBenchmark': [],
|
| +};
|
| +
|
| +Iterable<int> objectCounts;
|
| +Iterable<int> mutationCounts;
|
| +
|
| +final ButtonElement goButton = querySelector('#go');
|
| +final InputElement objectCountInput = querySelector('#objectCountInput');
|
| +final InputElement mutationCountInput = querySelector('#mutationCountInput');
|
| +final SpanElement mutationCountWrapper = querySelector('#mutationCountWrapper');
|
| +final SpanElement statusSpan = querySelector('#status');
|
| +final DivElement canvasWrapper = querySelector('#canvasWrapper');
|
| +final SelectElement benchmarkSelect = querySelector('#benchmarkSelect');
|
| +final SelectElement configSelect = querySelector('#configSelect');
|
| +final UListElement legendList = querySelector('#legendList');
|
| +final List<List<String>> colors = [
|
| + [0, 0, 255],
|
| + [138, 43, 226],
|
| + [165, 42, 42],
|
| + [100, 149, 237],
|
| + [220, 20, 60],
|
| + [184, 134, 11]
|
| +].map((rgb) => 'rgba(' + rgb.join(',') + ',.7)').toList();
|
| +
|
| +main() {
|
| + // TODO(jakemac): Use a transformer to generate the smoke config so we can see
|
| + // how that affects the benchmark.
|
| + useMirrors();
|
| +
|
| + benchmarkSelect.onChange.listen((_) => changeBenchmark());
|
| + changeBenchmark();
|
| +
|
| + goButton.onClick.listen((_) async {
|
| + canvasWrapper.children.clear();
|
| + goButton.disabled = true;
|
| + goButton.text = 'Running...';
|
| + legendList.text = '';
|
| + objectCounts =
|
| + objectCountInput.value.split(',').map((val) => int.parse(val));
|
| +
|
| + if (benchmarkSelect.value.startsWith('Setup')) {
|
| + mutationCounts = [0];
|
| + } else {
|
| + mutationCounts =
|
| + mutationCountInput.value.split(',').map((val) => int.parse(val));
|
| + }
|
| +
|
| + var i = 0;
|
| + mutationCounts.forEach((count) {
|
| + var li = document.createElement('li');
|
| + li.text = '$count mutations.';
|
| + li.style.color = colors[i % colors.length];
|
| + legendList.append(li);
|
| + i++;
|
| + });
|
| +
|
| + var results = [];
|
| + for (int objectCount in objectCounts) {
|
| + int x = 0;
|
| + for (int mutationCount in mutationCounts) {
|
| + statusSpan.text =
|
| + 'Testing: $objectCount objects with $mutationCount mutations';
|
| + // Let the status text render before running the next benchmark.
|
| + await new Future(() {});
|
| + var factory = benchmarkFactories[benchmarkSelect.value];
|
| + var benchmark = factory(objectCount, mutationCount, configSelect.value);
|
| + // Divide by 10 because benchmark_harness returns the amount of time it
|
| + // took to run 10 times, not once :(.
|
| + var resultMicros = benchmark.measure() / 10;
|
| +
|
| + if (results.length <= x) results.add([]);
|
| + results[x].add(resultMicros / 1000);
|
| + x++;
|
| + }
|
| + }
|
| +
|
| + drawBenchmarks(results);
|
| + });
|
| +}
|
| +
|
| +void drawBenchmarks(List<List<double>> results) {
|
| + var datasets = [];
|
| + for (int i = 0; i < results.length; i++) {
|
| + datasets.add({
|
| + 'fillColor': 'rgba(255, 255, 255, 0)',
|
| + 'strokeColor': colors[i % colors.length],
|
| + 'pointColor': colors[i % colors.length],
|
| + 'pointStrokeColor': "#fff",
|
| + 'data': results[i],
|
| + });
|
| + }
|
| + var data = {
|
| + 'labels': objectCounts.map((c) => '$c').toList(),
|
| + 'datasets': datasets,
|
| + };
|
| +
|
| + new Line(data, {'bezierCurve': false,}).show(canvasWrapper);
|
| + goButton.disabled = false;
|
| + goButton.text = 'Run Benchmarks';
|
| + statusSpan.text = '';
|
| +}
|
| +
|
| +void changeBenchmark() {
|
| + var configs = benchmarkConfigs[benchmarkSelect.value];
|
| + configSelect.text = '';
|
| + configs.forEach((config) {
|
| + var option = document.createElement('option');
|
| + option.text = config;
|
| + configSelect.append(option);
|
| + });
|
| +
|
| + document.title = benchmarkSelect.value;
|
| +
|
| + // Don't show the configSelect if there are no configs.
|
| + if (configs.isEmpty) {
|
| + configSelect.style.display = 'none';
|
| + } else {
|
| + configSelect.style.display = 'inline';
|
| + }
|
| +
|
| + // Don't show the mutation counts box if running a Setup* benchmark.
|
| + if (benchmarkSelect.value.startsWith('Setup')) {
|
| + mutationCountWrapper.style.display = 'none';
|
| + } else {
|
| + mutationCountWrapper.style.display = 'inline';
|
| + }
|
| +}
|
|
|