Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Side by Side Diff: tools/testing/perf_testing/smoketest/BenchmarkBase.dart

Issue 9139031: Make browser "sometest" like a regular test run by test.dart/py instead of (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011, 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
5 /** Accessors for our Singleton variables. */
6 BenchmarkSuite get BENCHMARK_SUITE() {
7 if (BenchmarkSuite._ONLY == null) {
8 BenchmarkSuite._ONLY = new BenchmarkSuite._internal();
9 }
10 return BenchmarkSuite._ONLY;
11 }
12
13 BenchmarkView get BENCHMARK_VIEW() {
14 if (BenchmarkView._ONLY == null) {
15 BenchmarkView._ONLY = new BenchmarkView._internal();
16 }
17 return BenchmarkView._ONLY;
18 }
19
20 /** The superclass from which all benchmarks inherit from. */
21 class BenchmarkBase {
22 /** Benchmark name. */
23 final String name;
24
25 const BenchmarkBase(String name) : this.name = name;
26
27 /**
28 * The benchmark code.
29 * This function is not used, if both [warmup] and [exercise] are overwritten.
30 */
31 void run() { }
32
33 /** Runs a short version of the benchmark. By default invokes [run] once. */
34 void warmup() {
35 run();
36 }
37
38 /** Exercices the benchmark. By default invokes [run] 10 times. */
39 void exercise() {
40 for (int i = 0; i < 10; i++) {
41 run();
42 }
43 }
44
45 /** Not measured setup code executed prior to the benchmark runs. */
46 void setup() { }
47
48 /** Not measures teardown code executed after the benchark runs. */
49 void teardown() { }
50
51 /**
52 * Measures the score for this benchmark by executing it repeately until
53 * time minimum has been reached.
54 */
55 static double measureFor(Function f, int timeMinimum) {
56 int time = 0;
57 int iter = 0;
58 Stopwatch watch = new Stopwatch();
59 watch.start();
60 int elapsed = 0;
61 while (elapsed < timeMinimum || iter < 32) {
62 f();
63 elapsed = watch.elapsedInMs();
64 iter++;
65 }
66 return (1000.0 * iter) / elapsed;
67 }
68
69 /**
70 * Measures the score for the benchmark and returns it.
71 * We measure iterations / sec (so bigger = better!).
72 */
73 double measure() {
74 setup();
75 // Warmup for at least 1000ms. Discard result.
76 measureFor(() { this.warmup(); }, 1000);
77 // Run the benchmark for at least 1000ms.
78 double result = measureFor(() { this.exercise(); }, 1000);
79 teardown();
80 return result;
81 }
82
83 void report() {
84 num score = measure();
85 Map<String, int> normalizingDict = {'Smoketest': 100};
86 window.console.log(name + " " + score.toString());
87 score = score / normalizingDict[name];
88 BENCHMARK_SUITE.updateIndividualScore(name, score);
89 }
90 }
91
92 /** The controller class that runs all of the benchmarks. */
93 class BenchmarkSuite {
94 /** The set of benchmarks that have yet to run. */
95 List<Function> benchmarks;
96
97 /**
98 * The set of scores from the benchmarks that have already run. (Used for
99 * calculating the Geometric mean).
100 */
101 List<num> scores;
102
103 /** The total number of benchmarks we will be running. */
104 int totalBenchmarks;
105
106 /** Singleton pattern: There's only one BenchmarkSuite. */
107 static BenchmarkSuite _ONLY = null;
108
109 BenchmarkSuite._internal() {
110 scores = [];
111 benchmarks = [() => Smoketest.main()];
112 totalBenchmarks = benchmarks.length;
113 }
114
115 /** Run all of the benchmarks that we have in our benchmarks list. */
116 runBenchmarks() {
117 runBenchmarksHelper(benchmarks);
118 }
119
120 /**
121 * Run the remaining benchmarks in our list. We chain the calls providing
122 * little breaks for the main page to gain control, so we don't force the
123 * entire page to hang the whole time.
124 */
125 runBenchmarksHelper(List<Function> remainingBenchmarks) {
126 // Remove the last benchmark, and run it.
127 var benchmark = remainingBenchmarks.removeLast();
128 benchmark();
129 if (remainingBenchmarks.length > 0) {
130 /* Provide small breaks between each benchmark, so that the browser
131 doesn't get unhappy about long running scripts, and so the user
132 can regain control of the UI to kill the page as needed. */
133 window.setTimeout(() => runBenchmarksHelper(remainingBenchmarks), 25);
134 } else if (remainingBenchmarks.length == 0) {
135 // We've run all of the benchmarks. Update the page with the score.
136 BENCHMARK_VIEW.setScore(geometricMean(scores));
137 }
138 }
139
140 /** Store the results of a single benchmark run. */
141 updateIndividualScore(String name, num score) {
142 scores.add(score);
143 BENCHMARK_VIEW.incrementProgress(name, score, totalBenchmarks);
144 }
145
146 /** Computes the geometric mean of a set of numbers. */
147 geometricMean(numbers) {
148 num log = 0;
149 for (num n in numbers) {
150 log += Math.log(n);
151 }
152 return Math.pow(Math.E, log / numbers.length);
153 }
154 }
155
156 /** Controls how results are displayed to the user, by updating the HTML. */
157 class BenchmarkView {
158
159 /** The number of benchmarks that have finished executing. */
160 int numCompleted = 0;
161
162 /** Singleton pattern: There's only one BenchmarkSuite. */
163 static BenchmarkView _ONLY = null;
164
165 BenchmarkView._internal();
166
167 /** Update the page HTML to show the calculated score. */
168 setScore(num score) {
169 String newScore = formatScore(score * 100.0);
170 Element status = document.query("#status");
171 status.innerHTML = "Score: $newScore <br>";
172 }
173
174 /**
175 * Update the page HTML to show how much progress we've made through the
176 * benchmarks.
177 */
178 incrementProgress(String name, num score, num totalBenchmarks) {
179 String newScore = formatScore(score * 100.0);
180 Element results = document.query("#results");
181 results.innerHTML += "$name: $newScore <br>";
182
183 Element status = document.query("#status");
184 numCompleted++;
185 // Slightly incorrect (truncating) percentage, but this is just to show
186 // the user we're making progress.
187 num percentage = 100 * numCompleted ~/ totalBenchmarks;
188 status.innerHTML = "Running: $percentage% completed.";
189 }
190
191 /**
192 * Rounds the score to have at least three significant digits (hopefully)
193 * helping readability of the scores.
194 */
195 String formatScore(num value) {
196 if (value > 100) {
197 return value.toStringAsFixed(0);
198 } else {
199 return value.toStringAsFixed(2);
200 }
201 }
202 }
OLDNEW
« no previous file with comments | « tools/testing/perf_testing/create_graph.py ('k') | tools/testing/perf_testing/smoketest/Smoketest.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698