2013-09-19 00:15:35 +00:00
|
|
|
// FIXME: Use the real promise if available.
|
|
|
|
// FIXME: Make sure this interface is compatible with the real Promise.
|
|
|
|
function SimplePromise() {
|
|
|
|
this._chainedPromise = null;
|
|
|
|
this._callback = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
SimplePromise.prototype.then = function (callback) {
|
|
|
|
if (this._callback)
|
2014-01-07 23:22:22 +00:00
|
|
|
throw "SimplePromise doesn't support multiple calls to then";
|
2013-09-19 00:15:35 +00:00
|
|
|
this._callback = callback;
|
|
|
|
this._chainedPromise = new SimplePromise;
|
|
|
|
|
|
|
|
if (this._resolved)
|
|
|
|
this.resolve(this._resolvedValue);
|
|
|
|
|
|
|
|
return this._chainedPromise;
|
|
|
|
}
|
|
|
|
|
|
|
|
SimplePromise.prototype.resolve = function (value) {
|
|
|
|
if (!this._callback) {
|
|
|
|
this._resolved = true;
|
|
|
|
this._resolvedValue = value;
|
2013-09-19 17:57:47 +00:00
|
|
|
return;
|
2013-09-19 00:15:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var result = this._callback(value);
|
|
|
|
if (result instanceof SimplePromise) {
|
2013-09-19 17:57:47 +00:00
|
|
|
var chainedPromise = this._chainedPromise;
|
|
|
|
result.then(function (result) { chainedPromise.resolve(result); });
|
2013-09-19 00:15:35 +00:00
|
|
|
} else
|
2013-09-19 17:57:47 +00:00
|
|
|
this._chainedPromise.resolve(result);
|
2013-09-19 00:15:35 +00:00
|
|
|
}
|
|
|
|
|
2014-01-07 23:22:22 +00:00
|
|
|
function BenchmarkTestStep(testName, testFunction) {
|
|
|
|
this.name = testName;
|
|
|
|
this.run = testFunction;
|
|
|
|
}
|
|
|
|
|
2014-01-08 03:58:16 +00:00
|
|
|
function BenchmarkRunner(suites, client) {
|
|
|
|
this._suites = suites;
|
|
|
|
this._prepareReturnValue = null;
|
|
|
|
this._client = client;
|
2013-09-19 00:15:35 +00:00
|
|
|
}
|
|
|
|
|
2014-01-08 03:58:16 +00:00
|
|
|
BenchmarkRunner.prototype.waitForElement = function (selector) {
|
2013-09-19 00:15:35 +00:00
|
|
|
var promise = new SimplePromise;
|
2014-01-08 03:58:16 +00:00
|
|
|
var contentDocument = this._frame.contentDocument;
|
2013-09-19 00:15:35 +00:00
|
|
|
|
|
|
|
function resolveIfReady() {
|
|
|
|
var element = contentDocument.querySelector(selector);
|
2013-09-19 17:57:47 +00:00
|
|
|
if (element)
|
|
|
|
return promise.resolve(element);
|
2013-09-19 00:15:35 +00:00
|
|
|
setTimeout(resolveIfReady, 50);
|
|
|
|
}
|
|
|
|
|
|
|
|
resolveIfReady();
|
|
|
|
return promise;
|
|
|
|
}
|
|
|
|
|
2014-01-08 03:58:16 +00:00
|
|
|
BenchmarkRunner.prototype._removeFrame = function () {
|
|
|
|
if (this._frame) {
|
|
|
|
this._frame.parentNode.removeChild(this._frame);
|
|
|
|
this._frame = null;
|
2013-09-19 00:15:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-08 03:58:16 +00:00
|
|
|
BenchmarkRunner.prototype._appendFrame = function (src) {
|
2013-09-19 00:15:35 +00:00
|
|
|
var frame = document.createElement('iframe');
|
2014-01-07 23:22:22 +00:00
|
|
|
frame.style.width = '800px';
|
2014-01-15 08:01:52 +00:00
|
|
|
frame.style.height = '600px';
|
|
|
|
frame.style.border = '0px none';
|
|
|
|
frame.style.position = 'absolute';
|
2014-06-01 03:04:10 +00:00
|
|
|
frame.setAttribute('scrolling', 'no');
|
2014-01-15 08:01:52 +00:00
|
|
|
|
2014-02-15 05:45:26 +00:00
|
|
|
var marginLeft = parseInt(getComputedStyle(document.body).marginLeft);
|
|
|
|
var marginTop = parseInt(getComputedStyle(document.body).marginTop);
|
|
|
|
if (window.innerWidth > 800 + marginLeft && window.innerHeight > 600 + marginTop) {
|
|
|
|
frame.style.left = marginLeft + 'px';
|
|
|
|
frame.style.top = marginTop + 'px';
|
2014-01-15 08:01:52 +00:00
|
|
|
} else {
|
|
|
|
frame.style.left = '0px';
|
|
|
|
frame.style.top = '0px';
|
|
|
|
}
|
|
|
|
|
2014-06-02 19:57:39 +00:00
|
|
|
if (this._client && this._client.willAddTestFrame)
|
|
|
|
this._client.willAddTestFrame(frame);
|
|
|
|
|
2014-01-15 08:01:52 +00:00
|
|
|
document.body.insertBefore(frame, document.body.firstChild);
|
2014-01-08 03:58:16 +00:00
|
|
|
this._frame = frame;
|
2013-09-19 00:15:35 +00:00
|
|
|
return frame;
|
|
|
|
}
|
|
|
|
|
2014-01-08 03:58:16 +00:00
|
|
|
BenchmarkRunner.prototype._waitAndWarmUp = function () {
|
2013-09-19 00:15:35 +00:00
|
|
|
var startTime = Date.now();
|
|
|
|
|
|
|
|
function Fibonacci(n) {
|
2013-09-19 17:57:47 +00:00
|
|
|
if (Date.now() - startTime > 100)
|
|
|
|
return;
|
|
|
|
if (n <= 0)
|
|
|
|
return 0;
|
|
|
|
else if (n == 1)
|
|
|
|
return 1;
|
|
|
|
return Fibonacci(n - 2) + Fibonacci(n - 1);
|
2013-09-19 00:15:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var promise = new SimplePromise;
|
|
|
|
setTimeout(function () {
|
2013-09-19 17:57:47 +00:00
|
|
|
Fibonacci(100);
|
|
|
|
promise.resolve();
|
2013-09-19 00:15:35 +00:00
|
|
|
}, 200);
|
|
|
|
return promise;
|
|
|
|
}
|
|
|
|
|
2017-07-18 23:22:46 +00:00
|
|
|
BenchmarkRunner.prototype._writeMark = function(name) {
|
|
|
|
if (window.performance && window.performance.mark)
|
|
|
|
window.performance.mark(name);
|
|
|
|
}
|
|
|
|
|
2013-09-19 00:15:35 +00:00
|
|
|
// This function ought be as simple as possible. Don't even use SimplePromise.
|
2017-07-18 23:22:46 +00:00
|
|
|
BenchmarkRunner.prototype._runTest = function(suite, test, prepareReturnValue, callback)
|
2013-09-19 00:15:35 +00:00
|
|
|
{
|
2017-07-18 23:22:46 +00:00
|
|
|
var self = this;
|
2013-09-19 00:15:35 +00:00
|
|
|
var now = window.performance && window.performance.now ? function () { return window.performance.now(); } : Date.now;
|
|
|
|
|
2017-07-18 23:22:46 +00:00
|
|
|
var contentWindow = self._frame.contentWindow;
|
|
|
|
var contentDocument = self._frame.contentDocument;
|
2013-09-19 00:15:35 +00:00
|
|
|
|
2017-08-19 03:05:57 +00:00
|
|
|
self._writeMark(suite.name + '.' + test.name + '-start');
|
2013-09-19 00:15:35 +00:00
|
|
|
var startTime = now();
|
2017-07-18 23:22:46 +00:00
|
|
|
test.run(prepareReturnValue, contentWindow, contentDocument);
|
2013-09-19 00:15:35 +00:00
|
|
|
var endTime = now();
|
2017-08-19 03:05:57 +00:00
|
|
|
self._writeMark(suite.name + '.' + test.name + '-sync-end');
|
2017-07-18 23:22:46 +00:00
|
|
|
|
2013-09-19 00:15:35 +00:00
|
|
|
var syncTime = endTime - startTime;
|
|
|
|
|
|
|
|
var startTime = now();
|
|
|
|
setTimeout(function () {
|
2017-08-23 21:40:41 +00:00
|
|
|
// Some browsers don't immediately update the layout for paint.
|
|
|
|
// Force the layout here to ensure we're measuring the layout time.
|
|
|
|
var height = self._frame.contentDocument.body.getBoundingClientRect().height;
|
2013-09-19 17:57:47 +00:00
|
|
|
var endTime = now();
|
2017-08-23 21:40:41 +00:00
|
|
|
self._frame.contentWindow._unusedHeightValue = height; // Prevent dead code elimination.
|
2017-08-19 03:05:57 +00:00
|
|
|
self._writeMark(suite.name + '.' + test.name + '-async-end');
|
2017-08-23 21:40:41 +00:00
|
|
|
callback(syncTime, endTime - startTime, height);
|
2013-09-19 00:15:35 +00:00
|
|
|
}, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
function BenchmarkState(suites) {
|
|
|
|
this._suites = suites;
|
|
|
|
this._suiteIndex = -1;
|
|
|
|
this._testIndex = 0;
|
|
|
|
this.next();
|
|
|
|
}
|
|
|
|
|
|
|
|
BenchmarkState.prototype.currentSuite = function() {
|
|
|
|
return this._suites[this._suiteIndex];
|
|
|
|
}
|
|
|
|
|
|
|
|
BenchmarkState.prototype.currentTest = function () {
|
|
|
|
var suite = this.currentSuite();
|
|
|
|
return suite ? suite.tests[this._testIndex] : null;
|
|
|
|
}
|
|
|
|
|
|
|
|
BenchmarkState.prototype.next = function () {
|
|
|
|
this._testIndex++;
|
|
|
|
|
|
|
|
var suite = this._suites[this._suiteIndex];
|
|
|
|
if (suite && this._testIndex < suite.tests.length)
|
|
|
|
return this;
|
|
|
|
|
|
|
|
this._testIndex = 0;
|
|
|
|
do {
|
|
|
|
this._suiteIndex++;
|
2014-01-07 23:22:22 +00:00
|
|
|
} while (this._suiteIndex < this._suites.length && this._suites[this._suiteIndex].disabled);
|
2013-09-19 00:15:35 +00:00
|
|
|
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
BenchmarkState.prototype.isFirstTest = function () {
|
|
|
|
return !this._testIndex;
|
|
|
|
}
|
|
|
|
|
2014-01-08 03:58:16 +00:00
|
|
|
BenchmarkState.prototype.prepareCurrentSuite = function (runner, frame) {
|
2013-09-19 00:15:35 +00:00
|
|
|
var suite = this.currentSuite();
|
|
|
|
var promise = new SimplePromise;
|
|
|
|
frame.onload = function () {
|
2014-01-08 03:58:16 +00:00
|
|
|
suite.prepare(runner, frame.contentWindow, frame.contentDocument).then(function (result) { promise.resolve(result); });
|
2013-09-19 00:15:35 +00:00
|
|
|
}
|
2014-02-05 07:00:45 +00:00
|
|
|
frame.src = 'resources/' + suite.url;
|
2013-09-19 00:15:35 +00:00
|
|
|
return promise;
|
|
|
|
}
|
|
|
|
|
2014-01-08 03:58:16 +00:00
|
|
|
BenchmarkRunner.prototype.step = function (state) {
|
2014-01-15 08:01:52 +00:00
|
|
|
if (!state) {
|
2014-01-08 03:58:16 +00:00
|
|
|
state = new BenchmarkState(this._suites);
|
Compute the final score using geometric mean in Speedometer 2.0
https://bugs.webkit.org/show_bug.cgi?id=172968
Reviewed by Saam Barati.
Make Speedometer 2.0 use the geometric mean of the subtotal of each test suite instead of the total..
In Speedometer 1.0, we used the total time to compute the final score because we wanted to make
the slowest framework and library faster. The fastest suite (FlightJS) still accounted for ~6% and
the slowest case (React) accounted for ~25% so we felt the total time, or the arithmetic mean with
a constant factor, was a good metric to track.
In the latest version of Speedometer 2.0, however, the fastest suite (Preact) runs in ~55ms whereas
the slowest suite (Inferno) takes 1.5s on Safari. Since the total time is 6.5s, Preact's suite only
accounts for ~0.8% of the total score while Inferno's suite accounts for ~23% of the total score.
Since the goal of Speedometer is to approximate different kinds of DOM API use patterns on the Web,
we want each framework & library to have some measurement impact on the overall benchmark score.
Furthermore, after r221205, we're testing both debug build of Ember.js as well as release build.
Since debug build is 4x slower, using the total time or the arithmetic mean thereof will effectively
give 4x as much weight to debug build of Ember.js relative to release build of Ember.js. Given only
~5% of websites that deploy Ember.js use debug build, this weighting is clearly not right.
This patch, therefore, replaces the arithmetic mean by the geometric mean to compute the final score.
It also moves the code to compute the final score to BenchmarkRunner to be shared between main.js
and InteractiveRunner.html.
* Speedometer/InteractiveRunner.html:
(.didRunSuites): Show geometric mean, arithmetic mean, total, as well as the score for completeness
since this is a debugging page for developers.
* Speedometer/resources/benchmark-runner.js:
(BenchmarkRunner.prototype.step): Added mean, geomean, and score as measuredValues' properties.
(BenchmarkRunner.prototype._runTestAndRecordResults): Removed the dead code.
(BenchmarkRunner.prototype._finalize): Compute and add total, arithmetic mean (just mean in the code),
and geometric mean (geomean) to measuredValues.
* Speedometer/resources/main.js:
(window.benchmarkClient): Replaced testsCount by stepsCount and _timeValues by _measuredValuesList.
(window.benchmarkClient.willRunTest):
(window.benchmarkClient.didRunTest):
(window.benchmarkClient.didRunSuites): Store measuredValues object instead of just the total time.
(window.benchmarkClient.didFinishLastIteration):
(window.benchmarkClient._computeResults):
(window.benchmarkClient._computeResults.valueForUnit): Renamed from totalTimeInDisplayUnit. Now simply
retrieves the values computed by BenchmarkRunner's_finalize.
(startBenchmark):
(computeScore): Deleted.
Canonical link: https://commits.webkit.org/193020@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@221659 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-09-06 02:37:41 +00:00
|
|
|
this._measuredValues = {tests: {}, total: 0, mean: NaN, geomean: NaN, score: NaN};
|
2014-01-15 08:01:52 +00:00
|
|
|
}
|
2013-09-19 00:15:35 +00:00
|
|
|
|
|
|
|
var suite = state.currentSuite();
|
|
|
|
if (!suite) {
|
2014-01-08 03:58:16 +00:00
|
|
|
this._finalize();
|
2013-09-19 00:15:35 +00:00
|
|
|
var promise = new SimplePromise;
|
|
|
|
promise.resolve();
|
|
|
|
return promise;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state.isFirstTest()) {
|
2017-05-19 09:43:40 +00:00
|
|
|
this._removeFrame();
|
2014-01-08 03:58:16 +00:00
|
|
|
var self = this;
|
|
|
|
return state.prepareCurrentSuite(this, this._appendFrame()).then(function (prepareReturnValue) {
|
2013-09-19 00:15:35 +00:00
|
|
|
self._prepareReturnValue = prepareReturnValue;
|
|
|
|
return self._runTestAndRecordResults(state);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2014-01-08 03:58:16 +00:00
|
|
|
return this._runTestAndRecordResults(state);
|
2013-09-19 00:15:35 +00:00
|
|
|
}
|
|
|
|
|
2014-01-15 08:01:52 +00:00
|
|
|
BenchmarkRunner.prototype.runAllSteps = function (startingState) {
|
|
|
|
var nextCallee = this.runAllSteps.bind(this);
|
|
|
|
this.step(startingState).then(function (nextState) {
|
|
|
|
if (nextState)
|
|
|
|
nextCallee(nextState);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
BenchmarkRunner.prototype.runMultipleIterations = function (iterationCount) {
|
|
|
|
var self = this;
|
|
|
|
var currentIteration = 0;
|
|
|
|
|
|
|
|
this._runNextIteration = function () {
|
|
|
|
currentIteration++;
|
|
|
|
if (currentIteration < iterationCount)
|
|
|
|
self.runAllSteps();
|
|
|
|
else if (this._client && this._client.didFinishLastIteration)
|
|
|
|
this._client.didFinishLastIteration();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this._client && this._client.willStartFirstIteration)
|
|
|
|
this._client.willStartFirstIteration(iterationCount);
|
|
|
|
|
|
|
|
self.runAllSteps();
|
|
|
|
}
|
|
|
|
|
2014-01-08 03:58:16 +00:00
|
|
|
BenchmarkRunner.prototype._runTestAndRecordResults = function (state) {
|
2013-09-19 00:15:35 +00:00
|
|
|
var promise = new SimplePromise;
|
|
|
|
var suite = state.currentSuite();
|
|
|
|
var test = state.currentTest();
|
|
|
|
|
2014-01-08 03:58:16 +00:00
|
|
|
if (this._client && this._client.willRunTest)
|
|
|
|
this._client.willRunTest(suite, test);
|
2014-01-07 23:22:22 +00:00
|
|
|
|
2014-01-08 03:58:16 +00:00
|
|
|
var self = this;
|
2013-09-19 00:15:35 +00:00
|
|
|
setTimeout(function () {
|
2017-07-18 23:22:46 +00:00
|
|
|
self._runTest(suite, test, self._prepareReturnValue, function (syncTime, asyncTime) {
|
2014-01-15 08:01:52 +00:00
|
|
|
var suiteResults = self._measuredValues.tests[suite.name] || {tests:{}, total: 0};
|
|
|
|
var total = syncTime + asyncTime;
|
|
|
|
self._measuredValues.tests[suite.name] = suiteResults;
|
|
|
|
suiteResults.tests[test.name] = {tests: {'Sync': syncTime, 'Async': asyncTime}, total: total};
|
|
|
|
suiteResults.total += total;
|
2014-01-07 23:22:22 +00:00
|
|
|
|
2014-02-15 05:45:26 +00:00
|
|
|
if (self._client && self._client.didRunTest)
|
2014-01-07 23:22:22 +00:00
|
|
|
self._client.didRunTest(suite, test);
|
|
|
|
|
2013-09-19 00:15:35 +00:00
|
|
|
state.next();
|
|
|
|
promise.resolve(state);
|
|
|
|
});
|
|
|
|
}, 0);
|
|
|
|
return promise;
|
|
|
|
}
|
|
|
|
|
2014-01-08 03:58:16 +00:00
|
|
|
BenchmarkRunner.prototype._finalize = function () {
|
|
|
|
this._removeFrame();
|
2013-09-19 00:15:35 +00:00
|
|
|
|
Compute the final score using geometric mean in Speedometer 2.0
https://bugs.webkit.org/show_bug.cgi?id=172968
Reviewed by Saam Barati.
Make Speedometer 2.0 use the geometric mean of the subtotal of each test suite instead of the total..
In Speedometer 1.0, we used the total time to compute the final score because we wanted to make
the slowest framework and library faster. The fastest suite (FlightJS) still accounted for ~6% and
the slowest case (React) accounted for ~25% so we felt the total time, or the arithmetic mean with
a constant factor, was a good metric to track.
In the latest version of Speedometer 2.0, however, the fastest suite (Preact) runs in ~55ms whereas
the slowest suite (Inferno) takes 1.5s on Safari. Since the total time is 6.5s, Preact's suite only
accounts for ~0.8% of the total score while Inferno's suite accounts for ~23% of the total score.
Since the goal of Speedometer is to approximate different kinds of DOM API use patterns on the Web,
we want each framework & library to have some measurement impact on the overall benchmark score.
Furthermore, after r221205, we're testing both debug build of Ember.js as well as release build.
Since debug build is 4x slower, using the total time or the arithmetic mean thereof will effectively
give 4x as much weight to debug build of Ember.js relative to release build of Ember.js. Given only
~5% of websites that deploy Ember.js use debug build, this weighting is clearly not right.
This patch, therefore, replaces the arithmetic mean by the geometric mean to compute the final score.
It also moves the code to compute the final score to BenchmarkRunner to be shared between main.js
and InteractiveRunner.html.
* Speedometer/InteractiveRunner.html:
(.didRunSuites): Show geometric mean, arithmetic mean, total, as well as the score for completeness
since this is a debugging page for developers.
* Speedometer/resources/benchmark-runner.js:
(BenchmarkRunner.prototype.step): Added mean, geomean, and score as measuredValues' properties.
(BenchmarkRunner.prototype._runTestAndRecordResults): Removed the dead code.
(BenchmarkRunner.prototype._finalize): Compute and add total, arithmetic mean (just mean in the code),
and geometric mean (geomean) to measuredValues.
* Speedometer/resources/main.js:
(window.benchmarkClient): Replaced testsCount by stepsCount and _timeValues by _measuredValuesList.
(window.benchmarkClient.willRunTest):
(window.benchmarkClient.didRunTest):
(window.benchmarkClient.didRunSuites): Store measuredValues object instead of just the total time.
(window.benchmarkClient.didFinishLastIteration):
(window.benchmarkClient._computeResults):
(window.benchmarkClient._computeResults.valueForUnit): Renamed from totalTimeInDisplayUnit. Now simply
retrieves the values computed by BenchmarkRunner's_finalize.
(startBenchmark):
(computeScore): Deleted.
Canonical link: https://commits.webkit.org/193020@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@221659 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-09-06 02:37:41 +00:00
|
|
|
if (this._client && this._client.didRunSuites) {
|
|
|
|
var product = 1;
|
|
|
|
var values = [];
|
|
|
|
for (var suiteName in this._measuredValues.tests) {
|
|
|
|
var suiteTotal = this._measuredValues.tests[suiteName].total;
|
|
|
|
product *= suiteTotal;
|
|
|
|
values.push(suiteTotal);
|
|
|
|
}
|
|
|
|
|
|
|
|
values.sort(function (a, b) { return a - b }); // Avoid the loss of significance for the sum.
|
|
|
|
var total = values.reduce(function (a, b) { return a + b });
|
|
|
|
var geomean = Math.pow(product, 1 / values.length);
|
|
|
|
|
|
|
|
var correctionFactor = 3; // This factor makes the test score look reasonably fit within 0 to 140.
|
|
|
|
this._measuredValues.total = total;
|
|
|
|
this._measuredValues.mean = total / values.length;
|
|
|
|
this._measuredValues.geomean = geomean;
|
|
|
|
this._measuredValues.score = 60 * 1000 / geomean / correctionFactor;
|
2014-01-08 03:58:16 +00:00
|
|
|
this._client.didRunSuites(this._measuredValues);
|
Compute the final score using geometric mean in Speedometer 2.0
https://bugs.webkit.org/show_bug.cgi?id=172968
Reviewed by Saam Barati.
Make Speedometer 2.0 use the geometric mean of the subtotal of each test suite instead of the total..
In Speedometer 1.0, we used the total time to compute the final score because we wanted to make
the slowest framework and library faster. The fastest suite (FlightJS) still accounted for ~6% and
the slowest case (React) accounted for ~25% so we felt the total time, or the arithmetic mean with
a constant factor, was a good metric to track.
In the latest version of Speedometer 2.0, however, the fastest suite (Preact) runs in ~55ms whereas
the slowest suite (Inferno) takes 1.5s on Safari. Since the total time is 6.5s, Preact's suite only
accounts for ~0.8% of the total score while Inferno's suite accounts for ~23% of the total score.
Since the goal of Speedometer is to approximate different kinds of DOM API use patterns on the Web,
we want each framework & library to have some measurement impact on the overall benchmark score.
Furthermore, after r221205, we're testing both debug build of Ember.js as well as release build.
Since debug build is 4x slower, using the total time or the arithmetic mean thereof will effectively
give 4x as much weight to debug build of Ember.js relative to release build of Ember.js. Given only
~5% of websites that deploy Ember.js use debug build, this weighting is clearly not right.
This patch, therefore, replaces the arithmetic mean by the geometric mean to compute the final score.
It also moves the code to compute the final score to BenchmarkRunner to be shared between main.js
and InteractiveRunner.html.
* Speedometer/InteractiveRunner.html:
(.didRunSuites): Show geometric mean, arithmetic mean, total, as well as the score for completeness
since this is a debugging page for developers.
* Speedometer/resources/benchmark-runner.js:
(BenchmarkRunner.prototype.step): Added mean, geomean, and score as measuredValues' properties.
(BenchmarkRunner.prototype._runTestAndRecordResults): Removed the dead code.
(BenchmarkRunner.prototype._finalize): Compute and add total, arithmetic mean (just mean in the code),
and geometric mean (geomean) to measuredValues.
* Speedometer/resources/main.js:
(window.benchmarkClient): Replaced testsCount by stepsCount and _timeValues by _measuredValuesList.
(window.benchmarkClient.willRunTest):
(window.benchmarkClient.didRunTest):
(window.benchmarkClient.didRunSuites): Store measuredValues object instead of just the total time.
(window.benchmarkClient.didFinishLastIteration):
(window.benchmarkClient._computeResults):
(window.benchmarkClient._computeResults.valueForUnit): Renamed from totalTimeInDisplayUnit. Now simply
retrieves the values computed by BenchmarkRunner's_finalize.
(startBenchmark):
(computeScore): Deleted.
Canonical link: https://commits.webkit.org/193020@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@221659 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-09-06 02:37:41 +00:00
|
|
|
}
|
2013-09-19 00:15:35 +00:00
|
|
|
|
2014-01-15 08:01:52 +00:00
|
|
|
if (this._runNextIteration)
|
|
|
|
this._runNextIteration();
|
2013-09-19 00:15:35 +00:00
|
|
|
}
|