Make DoYouEvenBench runnable by run-perf-tests
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 15 Jan 2014 08:01:52 +0000 (08:01 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 15 Jan 2014 08:01:52 +0000 (08:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=127030

Reviewed by Andreas Kling.

PerformanceTests:

Added Full.html that runs 5 iterations of DoYouEvenBench. This is the canonical DoYouEvenBench,
which is also runnable by run-perf-tests.

* DoYouEvenBench/Full.html: Added.

* DoYouEvenBench/benchmark.html:
(startTest): Updated the code to account for the fact old measuredValues is pushed down to tests
property and we now have total property so that we don't have to manually compute the total.

* DoYouEvenBench/resources/benchmark-report.js: Added. When we're inside a DRT/WTR, use
PerfTestRunner to output that can be parsed by run-perf-tests. Do the same when the query part
or the fragment part of the current URL is "webkit" for debugging purposes.

* DoYouEvenBench/resources/benchmark-runner.js:
(BenchmarkRunner):
(BenchmarkRunner.prototype._appendFrame): Position the frame at (0, 0) inside DRT and WTR since
we have exactly 800px by 600px inside those two test runners. Also always insert the iframe as
the first child of body to avoid inserting it after the pre inserted by the test runner.
(BenchmarkRunner.prototype.step): Initializes _measuredValues.
(BenchmarkRunner.prototype.runAllSteps): Merged callNextStep in benchmark.html.
(BenchmarkRunner.prototype.runMultipleIterations): Added.
(BenchmarkRunner.prototype._runTestAndRecordResults): Compute the grand total among suites.
Also push down the sync and async time into tests property for consistency.
(BenchmarkRunner.prototype._finalize):

* Dromaeo/resources/dromaeorunner.js:
(DRT.testObject): Renamed dromaeoIterationCount to customIterationCount as this option is also
used by DoYouEvenBench.

* resources/runner.js: Ditto.
(.finish): Spit out the aggregator name.

Tools:

Ignore console messages spit out by DoYouEvenBench and support aggregator names such as
":Total" to appear at the end of a test name. We don't do anything with it for now.

* Scripts/webkitpy/performance_tests/perftest.py:
(PerfTest._metrics_regex): Handle aggregator names such as ":Total". We'll pass it down
to the JSON in a follow up patch for the perf dashboard.
(PerfTest._lines_to_ignore_in_parser_result): Added lines to ignore for DoYouEvenBench.

LayoutTests:

Use customIterationCount as it has been renamed from dromaeoIterationCount.

* fast/harness/perftests/runs-per-second-iterations.html:

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

LayoutTests/ChangeLog
LayoutTests/fast/harness/perftests/runs-per-second-iterations.html
PerformanceTests/ChangeLog
PerformanceTests/DoYouEvenBench/Full.html [new file with mode: 0644]
PerformanceTests/DoYouEvenBench/benchmark.html
PerformanceTests/DoYouEvenBench/resources/benchmark-report.js [new file with mode: 0644]
PerformanceTests/DoYouEvenBench/resources/benchmark-runner.js
PerformanceTests/Dromaeo/resources/dromaeorunner.js
PerformanceTests/resources/runner.js
Tools/ChangeLog
Tools/Scripts/webkitpy/performance_tests/perftest.py

index 4e876f248ec04fb82f9158b8bf0982b064857bf8..9901ab3ab9ca112fd18f19cbb4a9b6b6eb219b86 100644 (file)
@@ -1,3 +1,14 @@
+2014-01-14  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Make DoYouEvenBench runnable by run-perf-tests
+        https://bugs.webkit.org/show_bug.cgi?id=127030
+
+        Reviewed by Andreas Kling.
+
+        Use customIterationCount as it has been renamed from dromaeoIterationCount.
+
+        * fast/harness/perftests/runs-per-second-iterations.html:
+
 2014-01-14  Dirk Schulze  <krit@webkit.org>
 
         Remove unnecessary WebkitCSSSVGDocumentValue
index 730f734819c1a14e34335809eff1cba8648f12c7..4278f02474865994bd1a25bbb8889bb0fb35ec49 100644 (file)
@@ -33,7 +33,7 @@ PerfTestRunner.measureRunsPerSecond({
             callsInIterations[i] = 0;
         callsInIterations[i]++;
     },
-    dromaeoIterationCount: 1,
+    customIterationCount: 1,
     done: function () {
         debug("Returning times: [" + originalTimesInIterations.join(", ") + "]");
         shouldEvaluateTo("callsInIterations[0]", 1);
index 222114acf22317cc3f6ce91a16b3f40f7a63b82e..214fa969c9879294611aec4f14947cb7da01d73f 100644 (file)
@@ -1,3 +1,42 @@
+2014-01-14  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Make DoYouEvenBench runnable by run-perf-tests
+        https://bugs.webkit.org/show_bug.cgi?id=127030
+
+        Reviewed by Andreas Kling.
+
+        Added Full.html that runs 5 iterations of DoYouEvenBench. This is the canonical DoYouEvenBench,
+        which is also runnable by run-perf-tests.
+
+        * DoYouEvenBench/Full.html: Added.
+
+        * DoYouEvenBench/benchmark.html:
+        (startTest): Updated the code to account for the fact old measuredValues is pushed down to tests
+        property and we now have total property so that we don't have to manually compute the total.
+
+        * DoYouEvenBench/resources/benchmark-report.js: Added. When we're inside a DRT/WTR, use
+        PerfTestRunner to output that can be parsed by run-perf-tests. Do the same when the query part
+        or the fragment part of the current URL is "webkit" for debugging purposes.
+
+        * DoYouEvenBench/resources/benchmark-runner.js:
+        (BenchmarkRunner):
+        (BenchmarkRunner.prototype._appendFrame): Position the frame at (0, 0) inside DRT and WTR since
+        we have exactly 800px by 600px inside those two test runners. Also always insert the iframe as
+        the first child of body to avoid inserting it after the pre inserted by the test runner.
+        (BenchmarkRunner.prototype.step): Initializes _measuredValues.
+        (BenchmarkRunner.prototype.runAllSteps): Merged callNextStep in benchmark.html.
+        (BenchmarkRunner.prototype.runMultipleIterations): Added.
+        (BenchmarkRunner.prototype._runTestAndRecordResults): Compute the grand total among suites.
+        Also push down the sync and async time into tests property for consistency.
+        (BenchmarkRunner.prototype._finalize):
+
+        * Dromaeo/resources/dromaeorunner.js:
+        (DRT.testObject): Renamed dromaeoIterationCount to customIterationCount as this option is also
+        used by DoYouEvenBench.
+
+        * resources/runner.js: Ditto.
+        (.finish): Spit out the aggregator name.
+
 2014-01-07  Ryosuke Niwa  <rniwa@webkit.org>
 
         DoYouEvenBench: Turn BenchmarkRunner into a real class
diff --git a/PerformanceTests/DoYouEvenBench/Full.html b/PerformanceTests/DoYouEvenBench/Full.html
new file mode 100644 (file)
index 0000000..f659ead
--- /dev/null
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>DoYouEvenBench</title>
+<script>
+
+(function () {
+    var values = [];
+    var pre = null;
+    var iterationNumber = 0;
+    window.benchmarkClient = {
+        didRunSuites: function (measuredValues) {
+            if (!pre) {
+                pre = document.createElement('pre');
+                pre.style.paddingTop = '600px';
+                document.body.appendChild(pre);
+            }
+            values.push(measuredValues.total);
+            iterationNumber++;
+            pre.appendChild(document.createTextNode('Iteration ' + iterationNumber + ': ' + measuredValues.total + 'ms\n'));
+        },
+        didFinishLastIteration: function () {
+            var sum = 0;
+            for (var i = 0; i < values.length; i++)
+                sum += values[i];
+            pre.appendChild(document.createTextNode('Average: ' + (sum / iterationNumber)  + 'ms\n'));
+            pre.style.paddingTop = 0;
+        }
+    }
+})();
+
+function startTest() {
+    var iterationCount = 5;
+    var runner = new BenchmarkRunner(Suites, benchmarkClient);
+    runner.runMultipleIterations(iterationCount);
+}
+
+</script>
+<script src="resources/benchmark-runner.js"></script>
+<script src="resources/benchmark-report.js"></script>
+<script src="resources/tests.js"></script>
+</head>
+<body onload="startTest()">
+</body>
+</html>
index 2a0b769dc8913eba18cd3276f8d8e22a266fdb22..97fd90b95b106395ef17eed35135583e78732f3c 100644 (file)
@@ -84,20 +84,18 @@ function startTest() {
         },
         didRunSuites: function (measuredValues) {
             var results = '';
-            var total = 0; // FIXME: Compute the total properly.
-            for (var suiteName in measuredValues) {
-                var suiteResults = measuredValues[suiteName];
+            for (var suiteName in measuredValues.tests) {
+                var suiteResults = measuredValues.tests[suiteName];
                 for (var testName in suiteResults.tests) {
                     var testResults = suiteResults.tests[testName];
-                    for (var subtestName in testResults) {
+                    for (var subtestName in testResults.tests) {
                         results += suiteName + ' : ' + testName + ' : ' + subtestName
-                            + ': ' + testResults[subtestName] + ' ms\n';
+                            + ': ' + testResults.tests[subtestName] + ' ms\n';
                     }
                 }
                 results += suiteName + ' : ' + suiteResults.total + ' ms\n';
-                total += suiteResults.total;
             }
-            results += 'Total : ' + total + ' ms\n';
+            results += 'Total : ' + measuredValues.total + ' ms\n';
 
             if (!results)
                 return;
@@ -109,18 +107,11 @@ function startTest() {
     });
 
     var currentState = null;
-    function callNextStep(state) {
-        runner.step(state).then(function (newState) {
-            currentState = newState;
-            if (newState)
-                callNextStep(newState);
-        });
-    }
 
     // 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); }));
+        function () { runner.runAllSteps(currentState); currentState = null; }));
 }
 
 window.addEventListener('load', startTest);
diff --git a/PerformanceTests/DoYouEvenBench/resources/benchmark-report.js b/PerformanceTests/DoYouEvenBench/resources/benchmark-report.js
new file mode 100644 (file)
index 0000000..0ea96c1
--- /dev/null
@@ -0,0 +1,73 @@
+// This file can be customized to report results as needed.
+
+(function () {
+    if (!window.testRunner && location.search != '?webkit' && location.hash != '#webkit')
+        return;
+
+    if (window.testRunner)
+        testRunner.waitUntilDone();
+
+    var scriptElement = document.createElement('script');
+    scriptElement.src = '../resources/runner.js';
+    document.head.appendChild(scriptElement);
+
+    var styleElement = document.createElement('style');
+    styleElement.textContent = 'pre { padding-top: 600px; }';
+    document.head.appendChild(styleElement);
+
+    var createTest;
+    var valuesByIteration = new Array;
+
+    window.benchmarkClient = {
+        willStartFirstIteration: function (iterationCount) {
+            createTest = function (name, aggregator, isLastTest) {
+                return {
+                    customIterationCount: iterationCount,
+                    doNotIgnoreInitialRun: true,
+                    doNotMeasureMemoryUsage: true,
+                    continueTesting: !isLastTest,
+                    unit: 'ms',
+                    name: name,
+                    aggregator: aggregator};
+            }
+            PerfTestRunner.prepareToMeasureValuesAsync(createTest(null, 'Total'));
+        },
+        didRunSuites: function (measuredValues) {
+            PerfTestRunner.measureValueAsync(measuredValues.total);
+            valuesByIteration.push(measuredValues.tests);
+        },
+        didFinishLastIteration: function () {
+            document.head.removeChild(document.querySelector('style'));
+
+            var measuredValuesByFullName = {};
+            function addToMeasuredValue(value, fullName, aggregator) {
+                var values = measuredValuesByFullName[fullName] || new Array;
+                measuredValuesByFullName[fullName] = values;
+                values.push(value);
+                values.aggregator = aggregator;
+            }
+
+            valuesByIteration.forEach(function (measuredValues) {
+                for (var suiteName in measuredValues) {
+                    var suite = measuredValues[suiteName];
+                    for (var testName in suite.tests) {
+                        var test = suite.tests[testName];
+                        for (var subtestName in test.tests)
+                            addToMeasuredValue(test.tests[subtestName], suiteName + '/' + testName + '/' + subtestName);
+                        addToMeasuredValue(test.total, suiteName + '/' + testName, 'Total');
+                    }
+                    addToMeasuredValue(suite.total, suiteName, 'Total');
+                }
+            });
+
+            var fullNames = new Array;
+            for (var fullName in measuredValuesByFullName)
+                fullNames.push(fullName);
+
+            for (var i = 0; i < fullNames.length; i++) {
+                var values = measuredValuesByFullName[fullNames[i]];
+                PerfTestRunner.reportValues(createTest(fullNames[i], values.aggregator, i + 1 == fullNames.length), values);
+            }
+        }
+    };
+})();
index 582c9af2e6fed9c1804034231c895f026ce41989..c596abf8fb568c5215de0ce8bf0752dd75121221 100644 (file)
@@ -40,7 +40,6 @@ function BenchmarkTestStep(testName, testFunction) {
 function BenchmarkRunner(suites, client) {
     this._suites = suites;
     this._prepareReturnValue = null;
-    this._measuredValues = {};
     this._client = client;
 }
 
@@ -69,8 +68,21 @@ BenchmarkRunner.prototype._removeFrame = function () {
 BenchmarkRunner.prototype._appendFrame = function (src) {
     var frame = document.createElement('iframe');
     frame.style.width = '800px';
-    frame.style.height = '600px'
-    document.body.appendChild(frame);
+    frame.style.height = '600px';
+    frame.style.border = '0px none';
+    frame.style.position = 'absolute';
+
+    var marginTop = document.body.style.marginTop;
+    var marginBottom = document.body.style.marginBottom;
+    if (window.innerWidth > 800 + marginTop && window.innerHeight > 600 + marginBottom) {
+        frame.style.left = marginTop + 'px';
+        frame.style.top = marginBottom + 'px';
+    } else {
+        frame.style.left = '0px';
+        frame.style.top = '0px';
+    }
+
+    document.body.insertBefore(frame, document.body.firstChild);
     this._frame = frame;
     return frame;
 }
@@ -162,8 +174,10 @@ BenchmarkState.prototype.prepareCurrentSuite = function (runner, frame) {
 }
 
 BenchmarkRunner.prototype.step = function (state) {
-    if (!state)
+    if (!state) {
         state = new BenchmarkState(this._suites);
+        this._measuredValues = {tests: {}, total: 0};
+    }
 
     var suite = state.currentSuite();
     if (!suite) {
@@ -185,6 +199,32 @@ BenchmarkRunner.prototype.step = function (state) {
     return this._runTestAndRecordResults(state);
 }
 
+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();
+}
+
 BenchmarkRunner.prototype._runTestAndRecordResults = function (state) {
     var promise = new SimplePromise;
     var suite = state.currentSuite();
@@ -196,10 +236,12 @@ BenchmarkRunner.prototype._runTestAndRecordResults = function (state) {
     var self = this;
     setTimeout(function () {
         self._runTest(suite, test.run, self._prepareReturnValue, function (syncTime, asyncTime) {
-            var suiteResults = self._measuredValues[suite.name] || {tests:{}, total: 0};
-            self._measuredValues[suite.name] = suiteResults;
-            suiteResults.tests[test.name] = {'Sync': syncTime, 'Async': asyncTime};
-            suiteResults.total += syncTime + asyncTime;
+            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;
+            self._measuredValues.total += total;
 
             if (self._client && self._client.willRunTest)
                 self._client.didRunTest(suite, test);
@@ -219,6 +261,6 @@ BenchmarkRunner.prototype._finalize = function () {
     if (this._client && this._client.didRunSuites)
         this._client.didRunSuites(this._measuredValues);
 
-    // FIXME: This should be done when we start running tests.
-    this._measuredValues = {};
+    if (this._runNextIteration)
+        this._runNextIteration();
 }
index d74c3e9762ddb1552ceeccac417f59ef18c9f0ba..1b05e8e805d51e4aba3ce8c26716faf9e9d4eedd 100644 (file)
@@ -32,7 +32,7 @@
          },
 
          testObject: function(name) {
-             return {dromaeoIterationCount: ITERATION_COUNT, doNotMeasureMemoryUsage: true, doNotIgnoreInitialRun: true, unit: 'runs/s',
+             return {customIterationCount: ITERATION_COUNT, doNotMeasureMemoryUsage: true, doNotIgnoreInitialRun: true, unit: 'runs/s',
                 name: name, continueTesting: !!name};
          },
 
index cf89331e158b186ebf148fcd8fe891b130acd093..ee1c6309fab782c15a3e5e7114a2734ecad2ade1 100755 (executable)
@@ -153,7 +153,7 @@ if (window.testRunner) {
         currentTest = test;
         // FIXME: We should be using multiple instances of test runner on Dromaeo as well but it's too slow now.
         // FIXME: Don't hard code the number of in-process iterations to use inside a test runner.
-        iterationCount = test.dromaeoIterationCount || (window.testRunner ? 5 : 20);
+        iterationCount = test.customIterationCount || (window.testRunner ? 5 : 20);
         completedIterations = -1;
         results = [];
         jsHeapResults = [];
@@ -220,8 +220,9 @@ if (window.testRunner) {
             var prefix = currentTest.name || '';
             if (currentTest.description)
                 PerfTestRunner.log("Description: " + currentTest.description);
-            metric = {'fps': 'FrameRate', 'runs/s': 'Runs', 'ms': 'Time'}[PerfTestRunner.unit]
-            PerfTestRunner.logStatistics(results, PerfTestRunner.unit, prefix + ":" + metric);
+            metric = {'fps': 'FrameRate', 'runs/s': 'Runs', 'ms': 'Time'}[PerfTestRunner.unit];
+            var suffix = currentTest.aggregation ? ':' + currentTest.aggregation : '';
+            PerfTestRunner.logStatistics(results, PerfTestRunner.unit, prefix + ":" + metric + suffix);
             if (jsHeapResults.length) {
                 PerfTestRunner.logStatistics(jsHeapResults, "bytes", prefix + ":JSHeap");
                 PerfTestRunner.logStatistics(mallocHeapResults, "bytes", prefix + ":Malloc");
index 73df56bb1c1cd3a6d1af1407bcdd6f91babdbaa0..0cf79288398797d087abb0281b4ef871e8483dae 100644 (file)
@@ -1,3 +1,18 @@
+2014-01-14  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Make DoYouEvenBench runnable by run-perf-tests
+        https://bugs.webkit.org/show_bug.cgi?id=127030
+
+        Reviewed by Andreas Kling.
+
+        Ignore console messages spit out by DoYouEvenBench and support aggregator names such as
+        ":Total" to appear at the end of a test name. We don't do anything with it for now.
+
+        * Scripts/webkitpy/performance_tests/perftest.py:
+        (PerfTest._metrics_regex): Handle aggregator names such as ":Total". We'll pass it down
+        to the JSON in a follow up patch for the perf dashboard.
+        (PerfTest._lines_to_ignore_in_parser_result): Added lines to ignore for DoYouEvenBench.
+
 2014-01-14  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [GTK] UI process crashes when the web process crashes while printing
index 4a9c7633f54e0e93d447d30e56bf34c797b59c8d..b88aa553adc6989c2083bc915b011cb7f5e56851 100644 (file)
@@ -168,7 +168,7 @@ class PerfTest(object):
             (median, unit, stdev, unit, sorted_values[0], unit, sorted_values[-1], unit))
 
     _description_regex = re.compile(r'^Description: (?P<description>.*)$', re.IGNORECASE)
-    _metrics_regex = re.compile(r'^(?P<subtest>[A-Za-z0-9\(\[].+)?:(?P<metric>[A-Z][A-Za-z]+) -> \[(?P<values>(\d+(\.\d+)?)(, \d+(\.\d+)?)+)\] (?P<unit>[a-z/]+)?$')
+    _metrics_regex = re.compile(r'^(?P<subtest>[A-Za-z0-9\(\[].+)?:(?P<metric>[A-Z][A-Za-z]+)(:(?P<aggregator>[A-Z][A-Za-z]+))? -> \[(?P<values>(\d+(\.\d+)?)(, \d+(\.\d+)?)+)\] (?P<unit>[a-z/]+)?$')
 
     def _run_with_driver(self, driver, time_out_ms):
         output = self.run_single(driver, self.test_path(), time_out_ms)
@@ -246,6 +246,17 @@ class PerfTest(object):
         re.compile(re.escape("""Blocked access to external URL http://www.whatwg.org/specs/web-apps/current-work/""")),
         re.compile(r"CONSOLE MESSAGE: (line \d+: )?Blocked script execution in '[A-Za-z0-9\-\.:]+' because the document's frame is sandboxed and the 'allow-scripts' permission is not set."),
         re.compile(r"CONSOLE MESSAGE: (line \d+: )?Not allowed to load local resource"),
+        # DoYouEvenBench
+        re.compile(re.escape("CONSOLE MESSAGE: line 140: Miss the info bar? Run TodoMVC from a server to avoid a cross-origin error.")),
+        re.compile(re.escape("CONSOLE MESSAGE: line 315: TypeError: Attempted to assign to readonly property.")),
+        re.compile(re.escape("CONSOLE MESSAGE: line 339: DEBUG: -------------------------------")),
+        re.compile(re.escape("CONSOLE MESSAGE: line 339: DEBUG: Ember.VERSION : 1.0.0-rc.1")),
+        re.compile(re.escape("CONSOLE MESSAGE: line 339: DEBUG: Handlebars.VERSION : 1.0.0-rc.3")),
+        re.compile(re.escape("CONSOLE MESSAGE: line 339: DEBUG: jQuery.VERSION : 1.9.1")),
+        re.compile(re.escape("CONSOLE MESSAGE: line 339: DEPRECATION: Namespaces should not begin with lowercase")),
+        re.compile(re.escape("processAllNamespaces@ember.js:4359:36")),
+        re.compile(re.escape("CONSOLE MESSAGE: line 124: Booting in DEBUG mode")),
+        re.compile(re.escape("CONSOLE MESSAGE: line 125: You can configure event logging with DEBUG.events.logAll()/logNone()/logByName()/logByAction()")),
     ]
 
     def _filter_output(self, output):