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 a3482f9c6ab2c376b1da81b14a96890be7493b79..222114acf22317cc3f6ce91a16b3f40f7a63b82e 100644 (file)
@@ -1,3 +1,30 @@
+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
index a5bdb56d5473559627434eee7e6d7796a1aa56e9..2a0b769dc8913eba18cd3276f8d8e22a266fdb22 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 6a14fa04c3a7ec479197bef040c5ccbd907392d2..582c9af2e6fed9c1804034231c895f026ce41989 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 597d892a1bf1be4b09089a8c21b53cb4d177aef6..9e508888069cceb529246e00a0db14e01ef721a8 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;
         });