Add new benchmark tests.
[WebKit-https.git] / PerformanceTests / Animometer / resources / runner / animometer.js
1 ResultsDashboard = Utilities.createClass(
2     function()
3     {
4         this._iterationsSamplers = [];
5         this._processedData = undefined;
6     }, {
7
8     push: function(suitesSamplers)
9     {
10         this._iterationsSamplers.push(suitesSamplers);
11     },
12
13     _processData: function()
14     {
15         var iterationsResults = [];
16         var iterationsScores = [];
17
18         this._iterationsSamplers.forEach(function(iterationSamplers, index) {
19             var suitesResults = {};
20             var suitesScores = [];
21
22             for (var suiteName in iterationSamplers) {
23                 var suite = suiteFromName(suiteName);
24                 var suiteSamplerData = iterationSamplers[suiteName];
25
26                 var testsResults = {};
27                 var testsScores = [];
28
29                 for (var testName in suiteSamplerData) {
30                     testsResults[testName] = suiteSamplerData[testName];
31                     testsScores.push(testsResults[testName][Strings.json.score]);
32                 }
33
34                 suitesResults[suiteName] =  {};
35                 suitesResults[suiteName][Strings.json.score] = Statistics.geometricMean(testsScores);
36                 suitesResults[suiteName][Strings.json.results.tests] = testsResults;
37                 suitesScores.push(suitesResults[suiteName][Strings.json.score]);
38             }
39
40             iterationsResults[index] = {};
41             iterationsResults[index][Strings.json.score] = Statistics.geometricMean(suitesScores);
42             iterationsResults[index][Strings.json.results.suites] = suitesResults;
43             iterationsScores.push(iterationsResults[index][Strings.json.score]);
44         });
45
46         this._processedData = {};
47         this._processedData[Strings.json.score] = Statistics.sampleMean(iterationsScores.length, iterationsScores.reduce(function(a, b) { return a * b; }));
48         this._processedData[Strings.json.results.iterations] = iterationsResults;
49     },
50
51     get data()
52     {
53         if (this._processedData)
54             return this._processedData;
55         this._processData();
56         return this._processedData;
57     },
58
59     get score()
60     {
61         return this.data[Strings.json.score];
62     }
63 });
64
65 ResultsTable = Utilities.createClass(
66     function(element, headers)
67     {
68         this.element = element;
69         this._headers = headers;
70
71         this._flattenedHeaders = [];
72         this._headers.forEach(function(header) {
73             if (header.disabled)
74                 return;
75
76             if (header.children)
77                 this._flattenedHeaders = this._flattenedHeaders.concat(header.children);
78             else
79                 this._flattenedHeaders.push(header);
80         }, this);
81
82         this._flattenedHeaders = this._flattenedHeaders.filter(function (header) {
83             return !header.disabled;
84         });
85
86         this.clear();
87     }, {
88
89     clear: function()
90     {
91         this.element.innerHTML = "";
92     },
93
94     _addHeader: function()
95     {
96         var thead = Utilities.createElement("thead", {}, this.element);
97         var row = Utilities.createElement("tr", {}, thead);
98
99         this._headers.forEach(function (header) {
100             if (header.disabled)
101                 return;
102
103             var th = Utilities.createElement("th", {}, row);
104             if (header.title != Strings.text.graph)
105                 th.textContent = header.title;
106             if (header.children)
107                 th.colSpan = header.children.length;
108         });
109     },
110
111     _addEmptyRow: function()
112     {
113         var row = Utilities.createElement("tr", {}, this.element);
114         this._flattenedHeaders.forEach(function (header) {
115             return Utilities.createElement("td", { class: "suites-separator" }, row);
116         });
117     },
118
119     _addTest: function(testName, testResults, options)
120     {
121         var row = Utilities.createElement("tr", {}, this.element);
122
123         this._flattenedHeaders.forEach(function (header) {
124             var td = Utilities.createElement("td", {}, row);
125             if (header.title == Strings.text.testName) {
126                 td.textContent = testName;
127             } else if (header.text) {
128                 var data = testResults[header.text];
129                 if (typeof data == "number")
130                     data = data.toFixed(2);
131                 td.textContent = data;
132             }
133         }, this);
134     },
135
136     _addSuite: function(suiteName, suiteResults, options)
137     {
138         for (var testName in suiteResults[Strings.json.results.tests]) {
139             var testResults = suiteResults[Strings.json.results.tests][testName];
140             this._addTest(testName, testResults, options);
141         }
142     },
143
144     _addIteration: function(iterationResult, options)
145     {
146         for (var suiteName in iterationResult[Strings.json.results.suites]) {
147             this._addEmptyRow();
148             this._addSuite(suiteName, iterationResult[Strings.json.results.suites][suiteName], options);
149         }
150     },
151
152     showIterations: function(iterationsResults, options)
153     {
154         this.clear();
155         this._addHeader();
156
157         iterationsResults.forEach(function(iterationResult) {
158             this._addIteration(iterationResult, options);
159         }, this);
160     }
161 });
162
163 window.benchmarkRunnerClient = {
164     iterationCount: 1,
165     options: null,
166     results: null,
167
168     initialize: function(suites, options)
169     {
170         this.options = options;
171     },
172
173     willStartFirstIteration: function()
174     {
175         this.results = new ResultsDashboard();
176     },
177
178     didRunSuites: function(suitesSamplers)
179     {
180         this.results.push(suitesSamplers);
181     },
182
183     didFinishLastIteration: function()
184     {
185         benchmarkController.showResults();
186     }
187 };
188
189 window.sectionsManager =
190 {
191     showSection: function(sectionIdentifier, pushState)
192     {
193         var currentSectionElement = document.querySelector("section.selected");
194         console.assert(currentSectionElement);
195
196         var newSectionElement = document.getElementById(sectionIdentifier);
197         console.assert(newSectionElement);
198
199         currentSectionElement.classList.remove("selected");
200         newSectionElement.classList.add("selected");
201
202         if (pushState)
203             history.pushState({section: sectionIdentifier}, document.title);
204     },
205
206     setSectionScore: function(sectionIdentifier, score, mean)
207     {
208         document.querySelector("#" + sectionIdentifier + " .score").textContent = score;
209         if (mean)
210             document.querySelector("#" + sectionIdentifier + " .mean").innerHTML = mean;
211     },
212
213     populateTable: function(tableIdentifier, headers, data)
214     {
215         var table = new ResultsTable(document.getElementById(tableIdentifier), headers);
216         table.showIterations(data, benchmarkRunnerClient.options);
217     }
218 };
219
220 window.benchmarkController = {
221     _startBenchmark: function(suites, options, frameContainerID)
222     {
223         benchmarkRunnerClient.initialize(suites, options);
224         var frameContainer = document.getElementById(frameContainerID);
225         var runner = new BenchmarkRunner(suites, frameContainer, benchmarkRunnerClient);
226         runner.runMultipleIterations();
227
228         sectionsManager.showSection("test-container");
229     },
230
231     startBenchmark: function()
232     {
233         var options = {
234             "test-interval": 10,
235             "display": "minimal",
236             "adjustment": "adaptive",
237             "frame-rate": 50,
238             "kalman-process-error": 1,
239             "kalman-measurement-error": 4,
240             "time-measurement": "performance"
241         };
242         this._startBenchmark(Suites, options, "test-container");
243     },
244
245     showResults: function()
246     {
247         if (!this.addedKeyEvent) {
248             document.addEventListener("keypress", this.selectResults, false);
249             this.addedKeyEvent = true;
250         }
251
252         sectionsManager.setSectionScore("results", benchmarkRunnerClient.results.score.toFixed(2));
253         var data = benchmarkRunnerClient.results.data[Strings.json.results.iterations];
254         sectionsManager.populateTable("results-header", Headers.testName, data);
255         sectionsManager.populateTable("results-score", Headers.score, data);
256         sectionsManager.showSection("results", true);
257     },
258
259     selectResults: function(event)
260     {
261         if (event.charCode != 115) // 's'
262             return;
263
264         event.target.selectRange = ((event.target.selectRange || 0) + 1) % 3;
265
266         var selection = window.getSelection();
267         selection.removeAllRanges();
268         var range = document.createRange();
269         switch (event.target.selectRange) {
270             case 0: {
271                 range.setStart(document.querySelector("#results .score"), 0);
272                 range.setEndAfter(document.querySelector("#results-score > tr:last-of-type"), 0);
273                 break;
274             }
275             case 1: {
276                 range.selectNodeContents(document.querySelector("#results .score"));
277                 break;
278             }
279             case 2: {
280                 range.selectNode(document.getElementById("results-score"));
281                 break;
282             }
283         }
284         selection.addRange(range);
285     }
286 };