OLD | NEW |
| (Empty) |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 library observe.test.benchmark.index; | |
5 | |
6 import 'dart:async'; | |
7 import 'dart:html'; | |
8 import 'package:benchmark_harness/benchmark_harness.dart'; | |
9 import 'package:chart/chart.dart'; | |
10 import 'package:observe/mirrors_used.dart'; // Makes output smaller. | |
11 import 'package:smoke/mirrors.dart'; | |
12 import 'object_benchmark.dart'; | |
13 import 'setup_object_benchmark.dart'; | |
14 import 'observable_list_benchmark.dart'; | |
15 import 'setup_observable_list_benchmark.dart'; | |
16 import 'path_benchmark.dart'; | |
17 import 'setup_path_benchmark.dart'; | |
18 | |
19 /// Benchmark names to factory functions. | |
20 typedef BenchmarkBase BenchmarkFactory( | |
21 int objectCount, int mutationCount, String config); | |
22 final Map<String, BenchmarkFactory> benchmarkFactories = { | |
23 'ObjectBenchmark': (int o, int m, String c) => new ObjectBenchmark(o, m, c), | |
24 'SetupObjectBenchmark': | |
25 (int o, int m, String c) => new SetupObjectBenchmark(o, c), | |
26 'ObservableListBenchmark': | |
27 (int o, int m, String c) => new ObservableListBenchmark(o, m, c), | |
28 'SetupObservableListBenchmark': | |
29 (int o, int m, String c) => new SetupObservableListBenchmark(o, c), | |
30 'PathBenchmark': (int o, int m, String c) => new PathBenchmark(o, m, c), | |
31 'SetupPathBenchmark': | |
32 (int o, int m, String c) => new SetupPathBenchmark(o, c), | |
33 }; | |
34 | |
35 /// Benchmark names to possible configs. | |
36 final Map<String, List<String>> benchmarkConfigs = { | |
37 'ObjectBenchmark': [], | |
38 'SetupObjectBenchmark': [], | |
39 'ObservableListBenchmark': ['splice', 'update', 'push/pop', 'shift/unshift'], | |
40 'SetupObservableListBenchmark': [], | |
41 'PathBenchmark': ['leaf', 'root'], | |
42 'SetupPathBenchmark': [], | |
43 }; | |
44 | |
45 Iterable<int> objectCounts; | |
46 Iterable<int> mutationCounts; | |
47 | |
48 final ButtonElement goButton = querySelector('#go'); | |
49 final InputElement objectCountInput = querySelector('#objectCountInput'); | |
50 final InputElement mutationCountInput = querySelector('#mutationCountInput'); | |
51 final SpanElement mutationCountWrapper = querySelector('#mutationCountWrapper'); | |
52 final SpanElement statusSpan = querySelector('#status'); | |
53 final DivElement canvasWrapper = querySelector('#canvasWrapper'); | |
54 final SelectElement benchmarkSelect = querySelector('#benchmarkSelect'); | |
55 final SelectElement configSelect = querySelector('#configSelect'); | |
56 final UListElement legendList = querySelector('#legendList'); | |
57 final List<List<String>> colors = [ | |
58 [0, 0, 255], | |
59 [138, 43, 226], | |
60 [165, 42, 42], | |
61 [100, 149, 237], | |
62 [220, 20, 60], | |
63 [184, 134, 11] | |
64 ].map((rgb) => 'rgba(' + rgb.join(',') + ',.7)').toList(); | |
65 | |
66 main() { | |
67 // TODO(jakemac): Use a transformer to generate the smoke config so we can see | |
68 // how that affects the benchmark. | |
69 useMirrors(); | |
70 | |
71 benchmarkSelect.onChange.listen((_) => changeBenchmark()); | |
72 changeBenchmark(); | |
73 | |
74 goButton.onClick.listen((_) async { | |
75 canvasWrapper.children.clear(); | |
76 goButton.disabled = true; | |
77 goButton.text = 'Running...'; | |
78 legendList.text = ''; | |
79 objectCounts = | |
80 objectCountInput.value.split(',').map((val) => int.parse(val)); | |
81 | |
82 if (benchmarkSelect.value.startsWith('Setup')) { | |
83 mutationCounts = [0]; | |
84 } else { | |
85 mutationCounts = | |
86 mutationCountInput.value.split(',').map((val) => int.parse(val)); | |
87 } | |
88 | |
89 var i = 0; | |
90 mutationCounts.forEach((count) { | |
91 var li = document.createElement('li'); | |
92 li.text = '$count mutations.'; | |
93 li.style.color = colors[i % colors.length]; | |
94 legendList.append(li); | |
95 i++; | |
96 }); | |
97 | |
98 var results = []; | |
99 for (int objectCount in objectCounts) { | |
100 int x = 0; | |
101 for (int mutationCount in mutationCounts) { | |
102 statusSpan.text = | |
103 'Testing: $objectCount objects with $mutationCount mutations'; | |
104 // Let the status text render before running the next benchmark. | |
105 await new Future(() {}); | |
106 var factory = benchmarkFactories[benchmarkSelect.value]; | |
107 var benchmark = factory(objectCount, mutationCount, configSelect.value); | |
108 // Divide by 10 because benchmark_harness returns the amount of time it | |
109 // took to run 10 times, not once :(. | |
110 var resultMicros = benchmark.measure() / 10; | |
111 | |
112 if (results.length <= x) results.add([]); | |
113 results[x].add(resultMicros / 1000); | |
114 x++; | |
115 } | |
116 } | |
117 | |
118 drawBenchmarks(results); | |
119 }); | |
120 } | |
121 | |
122 void drawBenchmarks(List<List<double>> results) { | |
123 var datasets = []; | |
124 for (int i = 0; i < results.length; i++) { | |
125 datasets.add({ | |
126 'fillColor': 'rgba(255, 255, 255, 0)', | |
127 'strokeColor': colors[i % colors.length], | |
128 'pointColor': colors[i % colors.length], | |
129 'pointStrokeColor': "#fff", | |
130 'data': results[i], | |
131 }); | |
132 } | |
133 var data = { | |
134 'labels': objectCounts.map((c) => '$c').toList(), | |
135 'datasets': datasets, | |
136 }; | |
137 | |
138 new Line(data, {'bezierCurve': false,}).show(canvasWrapper); | |
139 goButton.disabled = false; | |
140 goButton.text = 'Run Benchmarks'; | |
141 statusSpan.text = ''; | |
142 } | |
143 | |
144 void changeBenchmark() { | |
145 var configs = benchmarkConfigs[benchmarkSelect.value]; | |
146 configSelect.text = ''; | |
147 configs.forEach((config) { | |
148 var option = document.createElement('option'); | |
149 option.text = config; | |
150 configSelect.append(option); | |
151 }); | |
152 | |
153 document.title = benchmarkSelect.value; | |
154 | |
155 // Don't show the configSelect if there are no configs. | |
156 if (configs.isEmpty) { | |
157 configSelect.style.display = 'none'; | |
158 } else { | |
159 configSelect.style.display = 'inline'; | |
160 } | |
161 | |
162 // Don't show the mutation counts box if running a Setup* benchmark. | |
163 if (benchmarkSelect.value.startsWith('Setup')) { | |
164 mutationCountWrapper.style.display = 'none'; | |
165 } else { | |
166 mutationCountWrapper.style.display = 'inline'; | |
167 } | |
168 } | |
OLD | NEW |