MeasurementCluster's addToSeries is slow
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 5 Aug 2016 20:19:27 +0000 (20:19 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 5 Aug 2016 20:19:27 +0000 (20:19 +0000)
https://bugs.webkit.org/show_bug.cgi?id=160581

Rubber-stamped by Chris Dumez.

The bulk of time was spent in MeasurementAdaptor.prototype.applyTo where we computed the interval.

Since some of data points are filtered out by TimeSeriesChart component before intervals are used,
we can significantly reduce the CPU time by lazily compute them. This patch reduces the runtime of
applyTo from ~60ms to ~30ms on my machine.

* public/v3/models/measurement-adaptor.js:
(MeasurementAdaptor.prototype.applyTo): Lazily compute and cache the interval. Also cache the build
object instead of always creating a new object.
* public/v3/models/measurement-cluster.js:
(MeasurementCluster.prototype.addToSeries): Call applyTo first before checking whether the point is
an outlier or its id to avoid extracting those values twice since they show up in the profiler. Also
use "of" instead "forEach" since "of" seems to be faster here.

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

Websites/perf.webkit.org/ChangeLog
Websites/perf.webkit.org/public/v3/models/measurement-adaptor.js
Websites/perf.webkit.org/public/v3/models/measurement-cluster.js

index 0373807..f642dfa 100644 (file)
@@ -1,5 +1,26 @@
 2016-08-04  Ryosuke Niwa  <rniwa@webkit.org>
 
+        MeasurementCluster's addToSeries is slow
+        https://bugs.webkit.org/show_bug.cgi?id=160581
+
+        Rubber-stamped by Chris Dumez.
+
+        The bulk of time was spent in MeasurementAdaptor.prototype.applyTo where we computed the interval.
+
+        Since some of data points are filtered out by TimeSeriesChart component before intervals are used,
+        we can significantly reduce the CPU time by lazily compute them. This patch reduces the runtime of
+        applyTo from ~60ms to ~30ms on my machine.
+
+        * public/v3/models/measurement-adaptor.js:
+        (MeasurementAdaptor.prototype.applyTo): Lazily compute and cache the interval. Also cache the build
+        object instead of always creating a new object.
+        * public/v3/models/measurement-cluster.js:
+        (MeasurementCluster.prototype.addToSeries): Call applyTo first before checking whether the point is
+        an outlier or its id to avoid extracting those values twice since they show up in the profiler. Also
+        use "of" instead "forEach" since "of" seems to be faster here.
+
+2016-08-04  Ryosuke Niwa  <rniwa@webkit.org>
+
         Syncing script's configuration duplicates a lot of boilerplate
         https://bugs.webkit.org/show_bug.cgi?id=160574
 
index 012359b..f4dcc2e 100644 (file)
@@ -47,11 +47,11 @@ class MeasurementAdaptor {
         var mean = row[this._meanIndex];
         var sum = row[this._sumIndex];
         var squareSum = row[this._squareSumIndex];
-        var revisionList = row[this._revisionsIndex];
         var buildId = row[this._buildIndex];
         var builderId = row[this._builderIndex];
-        var buildNumber = row[this._buildNumberIndex];
-        var buildTime = row[this._buildTimeIndex];
+        var cachedBuild = null;
+        var cachedInterval = null;
+
         var self = this;
         return {
             id: id,
@@ -59,14 +59,22 @@ class MeasurementAdaptor {
             buildId: buildId,
             metricId: null,
             configType: null,
-            rootSet: function () { return MeasurementRootSet.ensureSingleton(id, revisionList); },
-            build: function () { return new Build(buildId, Builder.findById(builderId), buildNumber, buildTime); },
+            rootSet: function () { return MeasurementRootSet.ensureSingleton(id, row[self._revisionsIndex]); },
+            build: function () {
+                if (cachedBuild == null)
+                    cachedBuild = new Build(buildId, Builder.findById(builderId), row[self._buildNumberIndex], row[self._buildTimeIndex]);
+                return cachedBuild;
+            },
             time: row[this._commitTimeIndex],
             value: mean,
             sum: sum,
             squareSum: squareSum,
             iterationCount: row[this._countIndex],
-            interval: MeasurementAdaptor.computeConfidenceInterval(row[this._countIndex], mean, sum, squareSum)
+            interval: function () {
+                if (cachedInterval == null)
+                    cachedInterval = MeasurementAdaptor.computeConfidenceInterval(row[self._countIndex], mean, sum, squareSum);
+                return cachedInterval;
+            }
         };
     }
 
index 71c3f33..e641847 100644 (file)
@@ -17,17 +17,14 @@ class MeasurementCluster {
             return;
 
         var self = this;
-        rawMeasurements.forEach(function (row) {
-            var id = self._adaptor.extractId(row);
-            if (id in idMap)
-                return;
-            if (self._adaptor.isOutlier(row) && !includeOutliers)
-                return;
-
-            idMap[id] = true;
-
-            series.append(self._adaptor.applyTo(row));
-        });
+        for (var row of rawMeasurements) {
+            var point = this._adaptor.applyTo(row);
+            if (point.id in idMap || (!includeOutliers && point.isOutlier))
+                continue;
+            idMap[point.id] = true;
+            point.cluster = this;
+            series.append(point);
+        }
     }
 }