DoYouEvenBench: Turn BenchmarkRunner into a real class
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Jan 2014 03:58:16 +0000 (03:58 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Jan 2014 03:58:16 +0000 (03:58 +0000)
https://bugs.webkit.org/show_bug.cgi?id=126613

Reviewed by Stephanie Lewis.

Made BenchmarkRunner an instantiatable class. Made tests.js simply create an array of suite objects
instead of calling BenchmarkRunner.Suite now that we can have mulitple instances of BenchmarkRunner.

* DoYouEvenBench/benchmark.html:
(formatTestName): Moved and renamed from BenchmarkRunner._testName.
(createUIForSuites): Extracted from a giant blob of code.
(startTest): Ditto.
* DoYouEvenBench/resources/benchmark-runner.js:
(BenchmarkRunner): Added.
(BenchmarkRunner.prototype.waitForElement):
(BenchmarkRunner.prototype._removeFrame):
(BenchmarkRunner.prototype._appendFrame):
(BenchmarkRunner.prototype._waitAndWarmUp):
(BenchmarkRunner.prototype._runTest):
(BenchmarkState.prototype.prepareCurrentSuite):
(BenchmarkRunner.prototype.step):
(BenchmarkRunner.prototype._runTestAndRecordResults):
(BenchmarkRunner.prototype._finalize):
* DoYouEvenBench/resources/tests.js:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@161480 268f45cc-cd09-0410-ab3c-d52691b4dbfc

PerformanceTests/ChangeLog
PerformanceTests/DoYouEvenBench/benchmark.html
PerformanceTests/DoYouEvenBench/resources/benchmark-runner.js
PerformanceTests/DoYouEvenBench/resources/tests.js

index a3482f9..222114a 100644 (file)
@@ -1,5 +1,32 @@
 2014-01-07  Ryosuke Niwa  <rniwa@webkit.org>
 
+        DoYouEvenBench: Turn BenchmarkRunner into a real class
+        https://bugs.webkit.org/show_bug.cgi?id=126613
+
+        Reviewed by Stephanie Lewis.
+
+        Made BenchmarkRunner an instantiatable class. Made tests.js simply create an array of suite objects
+        instead of calling BenchmarkRunner.Suite now that we can have mulitple instances of BenchmarkRunner.
+
+        * DoYouEvenBench/benchmark.html:
+        (formatTestName): Moved and renamed from BenchmarkRunner._testName.
+        (createUIForSuites): Extracted from a giant blob of code.
+        (startTest): Ditto.
+        * DoYouEvenBench/resources/benchmark-runner.js:
+        (BenchmarkRunner): Added.
+        (BenchmarkRunner.prototype.waitForElement):
+        (BenchmarkRunner.prototype._removeFrame):
+        (BenchmarkRunner.prototype._appendFrame):
+        (BenchmarkRunner.prototype._waitAndWarmUp):
+        (BenchmarkRunner.prototype._runTest):
+        (BenchmarkState.prototype.prepareCurrentSuite):
+        (BenchmarkRunner.prototype.step):
+        (BenchmarkRunner.prototype._runTestAndRecordResults):
+        (BenchmarkRunner.prototype._finalize):
+        * DoYouEvenBench/resources/tests.js:
+
+2014-01-07  Ryosuke Niwa  <rniwa@webkit.org>
+
         DoYouEvenBench: Extract tests and runner code from benchmark.js/html
         https://bugs.webkit.org/show_bug.cgi?id=126596
 
index a5bdb56..2a0b769 100644 (file)
@@ -16,11 +16,12 @@ nav { position: absolute; right: 10px; }
 <body>
 <script>
 
-window.addEventListener('load', function () {
-    var self = BenchmarkRunner;
-    var control = document.createElement('nav');
+function formatTestName(suiteName, testName) {
+    return suiteName + (testName ? '/' + testName : '');
+}
 
-    var suites = BenchmarkRunner._suites;
+function createUIForSuites(suites, onstep, onrun) {
+    var control = document.createElement('nav');
     var ol = document.createElement('ol');
     var checkboxes = [];
     for (var suiteIndex = 0; suiteIndex < suites.length; suiteIndex++) {
@@ -36,7 +37,7 @@ window.addEventListener('load', function () {
 
         li.appendChild(checkbox);
         var label = document.createElement('label');
-        label.appendChild(document.createTextNode(self._testName(suite)));
+        label.appendChild(document.createTextNode(formatTestName(suite.name)));
         li.appendChild(label);
         label.htmlFor = checkbox.id;
 
@@ -47,7 +48,7 @@ window.addEventListener('load', function () {
             var anchor = document.createElement('a');
             anchor.id = suite.name + '-' + test.name;
             test.anchor = anchor;
-            anchor.appendChild(document.createTextNode(self._testName(suite, test.name)));
+            anchor.appendChild(document.createTextNode(formatTestName(suite.name, test.name)));
             testItem.appendChild(anchor);
             testList.appendChild(testItem);
         }
@@ -58,7 +59,21 @@ window.addEventListener('load', function () {
 
     control.appendChild(ol);
 
-    BenchmarkRunner.setClient({
+    var button = document.createElement('button');
+    button.textContent = 'Step';
+    button.onclick = onstep;
+    control.appendChild(button);
+
+    var button = document.createElement('button');
+    button.textContent = 'Run';
+    button.onclick = onrun;
+    control.appendChild(button);
+
+    return control;
+}
+
+function startTest() {
+    var runner = new BenchmarkRunner(Suites, {
         willRunTest: function (suite, test) {
             test.anchor.classList.add('running');
         },
@@ -94,30 +109,21 @@ window.addEventListener('load', function () {
     });
 
     var currentState = null;
-
-    // Don't call step while step is already executing.
-    var button = document.createElement('button');
-    button.textContent = 'Step';
-    button.onclick = function () {
-        self.step(currentState).then(function (state) { currentState = state; });
-    }
-    control.appendChild(button);
-
     function callNextStep(state) {
-        self.step(state).then(function (newState) {
+        runner.step(state).then(function (newState) {
             currentState = newState;
             if (newState)
                 callNextStep(newState);
         });
     }
 
-    var button = document.createElement('button');
-    button.textContent = 'Run';
-    button.onclick = function () { callNextStep(currentState); }
-    control.appendChild(button);
+    // Don't call step while step is already executing.
+    document.body.appendChild(createUIForSuites(Suites,
+        function () { runner.step(currentState).then(function (state) { currentState = state; }); },
+        function () { callNextStep(currentState); }));
+}
 
-    document.body.appendChild(control);
-});
+window.addEventListener('load', startTest);
 
 </script>
 </body>
index 6a14fa0..582c9af 100644 (file)
@@ -37,20 +37,16 @@ function BenchmarkTestStep(testName, testFunction) {
     this.run = testFunction;
 }
 
-var BenchmarkRunner = {_suites: [], _prepareReturnValue: null, _measuredValues: {}, _client: null};
-
-BenchmarkRunner.suite = function (suite) {
-    BenchmarkRunner._suites.push(suite);
-}
-
-BenchmarkRunner.setClient = function (client) {
-    BenchmarkRunner._client = client;
+function BenchmarkRunner(suites, client) {
+    this._suites = suites;
+    this._prepareReturnValue = null;
+    this._measuredValues = {};
+    this._client = client;
 }
 
-BenchmarkRunner.waitForElement = function (selector) {
-    var self = BenchmarkRunner;
+BenchmarkRunner.prototype.waitForElement = function (selector) {
     var promise = new SimplePromise;
-    var contentDocument = self._frame.contentDocument;
+    var contentDocument = this._frame.contentDocument;
 
     function resolveIfReady() {
         var element = contentDocument.querySelector(selector);
@@ -63,25 +59,23 @@ BenchmarkRunner.waitForElement = function (selector) {
     return promise;
 }
 
-BenchmarkRunner._removeFrame = function () {
-    var self = BenchmarkRunner;
-    if (self._frame) {
-        self._frame.parentNode.removeChild(self._frame);
-        self._frame = null;
+BenchmarkRunner.prototype._removeFrame = function () {
+    if (this._frame) {
+        this._frame.parentNode.removeChild(this._frame);
+        this._frame = null;
     }
 }
 
-BenchmarkRunner._appendFrame = function (src) {
-    var self = BenchmarkRunner;
+BenchmarkRunner.prototype._appendFrame = function (src) {
     var frame = document.createElement('iframe');
     frame.style.width = '800px';
     frame.style.height = '600px'
     document.body.appendChild(frame);
-    self._frame = frame;
+    this._frame = frame;
     return frame;
 }
 
-BenchmarkRunner._waitAndWarmUp = function () {
+BenchmarkRunner.prototype._waitAndWarmUp = function () {
     var startTime = Date.now();
 
     function Fibonacci(n) {
@@ -103,13 +97,12 @@ BenchmarkRunner._waitAndWarmUp = function () {
 }
 
 // This function ought be as simple as possible. Don't even use SimplePromise.
-BenchmarkRunner._runTest = function(suite, testFunction, prepareReturnValue, callback)
+BenchmarkRunner.prototype._runTest = function(suite, testFunction, prepareReturnValue, callback)
 {
-    var self = BenchmarkRunner;
     var now = window.performance && window.performance.now ? function () { return window.performance.now(); } : Date.now;
 
-    var contentWindow = self._frame.contentWindow;
-    var contentDocument = self._frame.contentDocument;
+    var contentWindow = this._frame.contentWindow;
+    var contentDocument = this._frame.contentDocument;
 
     var startTime = now();
     testFunction(prepareReturnValue, contentWindow, contentDocument);
@@ -123,12 +116,6 @@ BenchmarkRunner._runTest = function(suite, testFunction, prepareReturnValue, cal
     }, 0);
 }
 
-BenchmarkRunner._testName = function (suite, testName, metric) {
-    if (!testName)
-        return suite.name;
-    return suite.name + '/' + testName + (metric ? '/' + metric : '');
-}
-
 function BenchmarkState(suites) {
     this._suites = suites;
     this._suiteIndex = -1;
@@ -164,51 +151,49 @@ BenchmarkState.prototype.isFirstTest = function () {
     return !this._testIndex;
 }
 
-BenchmarkState.prototype.prepareCurrentSuite = function (frame) {
-    var self = this;
+BenchmarkState.prototype.prepareCurrentSuite = function (runner, frame) {
     var suite = this.currentSuite();
     var promise = new SimplePromise;
     frame.onload = function () {
-        suite.prepare(frame.contentWindow, frame.contentDocument).then(function (result) { promise.resolve(result); });
+        suite.prepare(runner, frame.contentWindow, frame.contentDocument).then(function (result) { promise.resolve(result); });
     }
     frame.src = suite.url;
     return promise;
 }
 
-BenchmarkRunner.step = function (state) {
-    var self = BenchmarkRunner;
-
+BenchmarkRunner.prototype.step = function (state) {
     if (!state)
-        state = new BenchmarkState(self._suites);
+        state = new BenchmarkState(this._suites);
 
     var suite = state.currentSuite();
     if (!suite) {
-        self._finalize();
+        this._finalize();
         var promise = new SimplePromise;
         promise.resolve();
         return promise;
     }
 
     if (state.isFirstTest()) {
-        self._masuredValuesForCurrentSuite = {};
-        return state.prepareCurrentSuite(self._appendFrame()).then(function (prepareReturnValue) {
+        this._masuredValuesForCurrentSuite = {};
+        var self = this;
+        return state.prepareCurrentSuite(this, this._appendFrame()).then(function (prepareReturnValue) {
             self._prepareReturnValue = prepareReturnValue;
             return self._runTestAndRecordResults(state);
         });
     }
 
-    return self._runTestAndRecordResults(state);
+    return this._runTestAndRecordResults(state);
 }
 
-BenchmarkRunner._runTestAndRecordResults = function (state) {
-    var self = BenchmarkRunner;
+BenchmarkRunner.prototype._runTestAndRecordResults = function (state) {
     var promise = new SimplePromise;
     var suite = state.currentSuite();
     var test = state.currentTest();
 
-    if (self._client && self._client.willRunTest)
-        self._client.willRunTest(suite, test);
+    if (this._client && this._client.willRunTest)
+        this._client.willRunTest(suite, test);
 
+    var self = this;
     setTimeout(function () {
         self._runTest(suite, test.run, self._prepareReturnValue, function (syncTime, asyncTime) {
             var suiteResults = self._measuredValues[suite.name] || {tests:{}, total: 0};
@@ -228,14 +213,12 @@ BenchmarkRunner._runTestAndRecordResults = function (state) {
     return promise;
 }
 
-BenchmarkRunner._finalize = function () {
-    var self = BenchmarkRunner;
-
-    self._removeFrame();
+BenchmarkRunner.prototype._finalize = function () {
+    this._removeFrame();
 
-    if (self._client && self._client.didRunSuites)
-        self._client.didRunSuites(self._measuredValues);
+    if (this._client && this._client.didRunSuites)
+        this._client.didRunSuites(this._measuredValues);
 
     // FIXME: This should be done when we start running tests.
-    self._measuredValues = {};
+    this._measuredValues = {};
 }
index 597d892..9e50888 100644 (file)
@@ -1,10 +1,11 @@
 var numberOfItemsToAdd = 100;
+var Suites = [];
 
-BenchmarkRunner.suite({
+Suites.push({
     name: 'VanillaJS-TodoMVC',
     url: 'todomvc/vanilla-examples/vanillajs/index.html',
-    prepare: function (contentWindow, contentDocument) {
-        return BenchmarkRunner.waitForElement('#new-todo').then(function (element) {
+    prepare: function (runner, contentWindow, contentDocument) {
+        return runner.waitForElement('#new-todo').then(function (element) {
             element.focus();
             return element;
         });
@@ -30,17 +31,17 @@ BenchmarkRunner.suite({
     ]
 });
 
-BenchmarkRunner.suite({
+Suites.push({
     name: 'EmberJS-TodoMVC',
     url: 'todomvc/architecture-examples/emberjs/index.html',
-    prepare: function (contentWindow, contentDocument) {
+    prepare: function (runner, contentWindow, contentDocument) {
         contentWindow.Todos.Store = contentWindow.DS.Store.extend({
             revision: 12,
             adapter: 'Todos.LSAdapter',
             commit: function () { }
         });
 
-        return BenchmarkRunner.waitForElement('#new-todo').then(function (element) {
+        return runner.waitForElement('#new-todo').then(function (element) {
             element.focus();
             return {
                 views: contentWindow.Ember.View.views,
@@ -70,12 +71,12 @@ BenchmarkRunner.suite({
     ]
 });
 
-BenchmarkRunner.suite({
+Suites.push({
     name: 'BackboneJS-TodoMVC',
     url: 'todomvc/architecture-examples/backbone/index.html',
-    prepare: function (contentWindow, contentDocument) {
+    prepare: function (runner, contentWindow, contentDocument) {
     contentWindow.Backbone.sync = function () {}
-        return BenchmarkRunner.waitForElement('#new-todo').then(function (element) {
+        return runner.waitForElement('#new-todo').then(function (element) {
             element.focus();
             return element;
         });
@@ -102,11 +103,11 @@ BenchmarkRunner.suite({
     ]
 });
 
-BenchmarkRunner.suite({
+Suites.push({
     name: 'jQuery-TodoMVC',
     url: 'todomvc/architecture-examples/jquery/index.html',
-    prepare: function (contentWindow, contentDocument) {
-        return BenchmarkRunner.waitForElement('#new-todo').then(function (element) {
+    prepare: function (runner, contentWindow, contentDocument) {
+        return runner.waitForElement('#new-todo').then(function (element) {
             element.focus();
             return element;
         });
@@ -158,11 +159,11 @@ BenchmarkRunner.suite({
     ]
 });
 
-BenchmarkRunner.suite({
+Suites.push({
     name: 'AngularJS-TodoMVC',
     url: 'todomvc/architecture-examples/angularjs/index.html',
-    prepare: function (contentWindow, contentDocument) {
-        return BenchmarkRunner.waitForElement('#new-todo').then(function (element) {
+    prepare: function (runner, contentWindow, contentDocument) {
+        return runner.waitForElement('#new-todo').then(function (element) {
             element.focus();
             return element;
         });
@@ -193,12 +194,12 @@ BenchmarkRunner.suite({
     ]
 });
 
-BenchmarkRunner.suite({
+Suites.push({
     name: 'React-TodoMVC',
     url: 'todomvc/labs/architecture-examples/react/index.html',
-    prepare: function (contentWindow, contentDocument) {
+    prepare: function (runner, contentWindow, contentDocument) {
         contentWindow.Utils.store = function () {}
-        return BenchmarkRunner.waitForElement('#new-todo').then(function (element) {
+        return runner.waitForElement('#new-todo').then(function (element) {
             element.focus();
             return element;
         });
@@ -229,11 +230,11 @@ BenchmarkRunner.suite({
 });
 
 var actionCount = 50;
-BenchmarkRunner.suite({
+Suites.push({
     name: 'FlightJS-MailClient',
     url: 'flightjs-example-app/index.html',
-    prepare: function (contentWindow, contentDocument) {
-        return BenchmarkRunner.waitForElement('.span8').then(function (element) {
+    prepare: function (runner, contentWindow, contentDocument) {
+        return runner.waitForElement('.span8').then(function (element) {
             element.focus();
             return element;
         });