<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[196296] trunk/PerformanceTests</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/196296">196296</a></dd>
<dt>Author</dt> <dd>jonlee@apple.com</dd>
<dt>Date</dt> <dd>2016-02-08 19:30:44 -0800 (Mon, 08 Feb 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Tests: reuse objects already made.

Avoid thrash of object creation and removal by maintaining an index that
moves along the array as the adjust values change. If the tune value
requires more objects than the maximum size of the object array, then create
new objects. This means that the object array size never decreases.

* Animometer/tests/master/resources/canvas-stage.js: Maintain a separate
offsetIndex. For these tests, we want to avoid drawing the oldest objects,
so the scene will draw the object at offsetIndex to the end of the array.
(tune): Reverse the logic since &quot;removal&quot; of objects is much simpler and
involves simply changing the offsetIndex.
(animate): Update the for loop to draw from offsetIndex to the end.
(complexity): Update the definition.
* Animometer/tests/master/resources/canvas-tests.js: Maintain a separate
offsetIndex. For these tests, we want to avoid drawing the newest objects,
so the scene will draw the object at index 0 to the object at offsetIndex.
(SimpleCanvasStage.animate): Fly-by removal of local stage variable,
which is unneeded. Update the for loop to draw from offsetIndex to the end.
* Animometer/tests/simple/resources/simple-canvas-paths.js:
(SimpleCanvasStage.animate): Update the for loop to draw from 0 to
offsetIndex.
* Animometer/tests/simple/resources/simple-canvas.js:
(tune): Update logic. Here, offsetIndex represents the boundary of the last
index to render.
(animate): Update the for loop to draw from 0 to offsetIndex.
(complexity): Update the definition.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkPerformanceTestsAnimometertestsmasterresourcescanvasstagejs">trunk/PerformanceTests/Animometer/tests/master/resources/canvas-stage.js</a></li>
<li><a href="#trunkPerformanceTestsAnimometertestsmasterresourcescanvastestsjs">trunk/PerformanceTests/Animometer/tests/master/resources/canvas-tests.js</a></li>
<li><a href="#trunkPerformanceTestsAnimometertestssimpleresourcessimplecanvaspathsjs">trunk/PerformanceTests/Animometer/tests/simple/resources/simple-canvas-paths.js</a></li>
<li><a href="#trunkPerformanceTestsAnimometertestssimpleresourcessimplecanvasjs">trunk/PerformanceTests/Animometer/tests/simple/resources/simple-canvas.js</a></li>
<li><a href="#trunkPerformanceTestsChangeLog">trunk/PerformanceTests/ChangeLog</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkPerformanceTestsAnimometertestsmasterresourcescanvasstagejs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/tests/master/resources/canvas-stage.js (196295 => 196296)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/tests/master/resources/canvas-stage.js        2016-02-09 03:30:42 UTC (rev 196295)
+++ trunk/PerformanceTests/Animometer/tests/master/resources/canvas-stage.js        2016-02-09 03:30:44 UTC (rev 196296)
</span><span class="lines">@@ -4,6 +4,7 @@
</span><span class="cx">         Stage.call(this);
</span><span class="cx">         this._canvasObject = canvasObject;
</span><span class="cx">         this.objects = [];
</span><ins>+        this.offsetIndex = 0;
</ins><span class="cx">     }, {
</span><span class="cx"> 
</span><span class="cx">     initialize: function(benchmark, options)
</span><span class="lines">@@ -17,27 +18,31 @@
</span><span class="cx">         if (count == 0)
</span><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        if (count &gt; 0) {
-            for (var i = 0; i &lt; count; ++i)
-                this.objects.push(new this._canvasObject(this));
</del><ins>+        if (count &lt; 0) {
+            this.offsetIndex = Math.min(this.offsetIndex - count, this.objects.length);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        count = Math.min(-count, this.objects.length);
-        this.objects.splice(0, count);
</del><ins>+        var newIndex = this.offsetIndex - count;
+        if (newIndex &lt; 0) {
+            this.offsetIndex = 0;
+            newIndex = -newIndex;
+            for (var i = 0; i &lt; newIndex; ++i)
+                this.objects.push(new this._canvasObject(this));
+        } else
+            this.offsetIndex = newIndex;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     animate: function()
</span><span class="cx">     {
</span><span class="cx">         var context = this.context;
</span><span class="cx">         context.clearRect(0, 0, this.size.x, this.size.y);
</span><del>-        this.objects.forEach(function(object) {
-            object.draw(context);
-        });
</del><ins>+        for (var i = this.offsetIndex, length = this.objects.length; i &lt; length; ++i)
+            this.objects[i].draw(context);
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     complexity: function()
</span><span class="cx">     {
</span><del>-        return this.objects.length;
</del><ins>+        return this.objects.length - this.offsetIndex;
</ins><span class="cx">     }
</span><span class="cx"> });
</span></span></pre></div>
<a id="trunkPerformanceTestsAnimometertestsmasterresourcescanvastestsjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/tests/master/resources/canvas-tests.js (196295 => 196296)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/tests/master/resources/canvas-tests.js        2016-02-09 03:30:42 UTC (rev 196295)
+++ trunk/PerformanceTests/Animometer/tests/master/resources/canvas-tests.js        2016-02-09 03:30:44 UTC (rev 196296)
</span><span class="lines">@@ -137,7 +137,6 @@
</span><span class="cx">     animate: function()
</span><span class="cx">     {
</span><span class="cx">         var context = this.context;
</span><del>-        var stage = this;
</del><span class="cx"> 
</span><span class="cx">         context.clearRect(0, 0, this.size.x, this.size.y);
</span><span class="cx">         context.lineWidth = 30;
</span><span class="lines">@@ -145,14 +144,13 @@
</span><span class="cx">             context.strokeStyle = [&quot;#e01040&quot;, &quot;#10c030&quot;, &quot;#e05010&quot;][i];
</span><span class="cx">             context.fillStyle = [&quot;#70051d&quot;, &quot;#016112&quot;, &quot;#702701&quot;][i];
</span><span class="cx">             context.beginPath();
</span><del>-                context.arc((0.5 + i) / 3 * stage.size.x, stage.size.y/2, stage.circleRadius, 0, Math.PI*2);
</del><ins>+                context.arc((0.5 + i) / 3 * this.size.x, this.size.y/2, this.circleRadius, 0, Math.PI*2);
</ins><span class="cx">             context.stroke();
</span><span class="cx">             context.fill();
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        this.objects.forEach(function(object) {
-            object.draw(context);
-        });
</del><ins>+        for (var i = this.offsetIndex, length = this.objects.length; i &lt; length; ++i)
+            this.objects[i].draw(context);
</ins><span class="cx">     }
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="lines">@@ -171,12 +169,12 @@
</span><span class="cx"> 
</span><span class="cx">     animate: function() {
</span><span class="cx">         var context = this.context;
</span><del>-        var stage = this;
</del><span class="cx"> 
</span><span class="cx">         context.clearRect(0, 0, this.size.x, this.size.y);
</span><span class="cx">         context.beginPath();
</span><del>-        this.objects.forEach(function(object, index) {
-            if (index == 0) {
</del><ins>+        for (var i = this.offsetIndex, length = this.objects.length; i &lt; length; ++i) {
+            var object = this.objects[i];
+            if (i == this.offsetIndex) {
</ins><span class="cx">                 context.lineWidth = object.width;
</span><span class="cx">                 context.strokeStyle = object.color;
</span><span class="cx">                 context.moveTo(object.point.x, object.point.y);
</span><span class="lines">@@ -194,7 +192,7 @@
</span><span class="cx">                 if (Math.random() &gt; 0.999)
</span><span class="cx">                     object.isSplit = !object.isSplit;
</span><span class="cx">             }
</span><del>-        });
</del><ins>+        }
</ins><span class="cx">         context.stroke();
</span><span class="cx">     }
</span><span class="cx"> });
</span></span></pre></div>
<a id="trunkPerformanceTestsAnimometertestssimpleresourcessimplecanvaspathsjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/tests/simple/resources/simple-canvas-paths.js (196295 => 196296)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/tests/simple/resources/simple-canvas-paths.js        2016-02-09 03:30:42 UTC (rev 196295)
+++ trunk/PerformanceTests/Animometer/tests/simple/resources/simple-canvas-paths.js        2016-02-09 03:30:44 UTC (rev 196296)
</span><span class="lines">@@ -224,9 +224,8 @@
</span><span class="cx">         context.strokeStyle = Stage.rotatingColor();
</span><span class="cx">         context.beginPath();
</span><span class="cx">         context.moveTo(this.size.x / 2, this.size.y / 2);
</span><del>-        this.objects.forEach(function(object) {
-            object.draw(context);
-        });
</del><ins>+        for (var i = 0, length = this.offsetIndex; i &lt; length; ++i)
+            this.objects[i].draw(context);
</ins><span class="cx">         context.stroke();
</span><span class="cx">     }
</span><span class="cx"> });
</span><span class="lines">@@ -243,9 +242,8 @@
</span><span class="cx">         context.fillStyle = Stage.rotatingColor();
</span><span class="cx">         context.beginPath();
</span><span class="cx">         context.moveTo(this.size.x / 2, this.size.y / 2);
</span><del>-        this.objects.forEach(function(object) {
-            object.draw(context);
-        });
</del><ins>+        for (var i = 0, length = this.offsetIndex; i &lt; length; ++i)
+            this.objects[i].draw(context);
</ins><span class="cx">         context.fill();
</span><span class="cx">     }
</span><span class="cx"> });
</span><span class="lines">@@ -298,9 +296,8 @@
</span><span class="cx">         context.lineDashOffset = this._step++;
</span><span class="cx">         context.beginPath();
</span><span class="cx">         context.moveTo(this.size.x / 2, this.size.y / 2);
</span><del>-        this.objects.forEach(function(object) {
-            object.draw(context);
-        });
</del><ins>+        for (var i = 0, length = this.offsetIndex; i &lt; length; ++i)
+            this.objects[i].draw(context);
</ins><span class="cx">         context.stroke();
</span><span class="cx">     }
</span><span class="cx"> });
</span></span></pre></div>
<a id="trunkPerformanceTestsAnimometertestssimpleresourcessimplecanvasjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/tests/simple/resources/simple-canvas.js (196295 => 196296)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/tests/simple/resources/simple-canvas.js        2016-02-09 03:30:42 UTC (rev 196295)
+++ trunk/PerformanceTests/Animometer/tests/simple/resources/simple-canvas.js        2016-02-09 03:30:44 UTC (rev 196296)
</span><span class="lines">@@ -4,16 +4,32 @@
</span><span class="cx">         if (count == 0)
</span><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        if (count &gt; 0) {
</del><ins>+        if (count &lt; 0) {
+            this.offsetIndex = Math.max(this.offsetIndex + count, 0);
+            return;
+        }
+
+        this.offsetIndex = this.offsetIndex + count;
+        if (this.offsetIndex &gt; this.objects.length) {
</ins><span class="cx">             // For some tests, it may be easier to see how well the test is going
</span><span class="cx">             // by limiting the range of coordinates in which new objects can reside
</span><span class="cx">             var coordinateMaximumFactor = Math.min(this.objects.length, Math.min(this.size.x, this.size.y)) / Math.min(this.size.x, this.size.y);
</span><del>-            for (var i = 0; i &lt; count; ++i)
</del><ins>+            var newIndex = this.offsetIndex - this.objects.length;
+            for (var i = 0; i &lt; newIndex; ++i)
</ins><span class="cx">                 this.objects.push(new this._canvasObject(this, coordinateMaximumFactor));
</span><del>-            return;
</del><span class="cx">         }
</span><ins>+    },
</ins><span class="cx"> 
</span><del>-        count = Math.min(-count, this.objects.length);
-        this.objects.splice(-count, count);
</del><ins>+    animate: function()
+    {
+        var context = this.context;
+        context.clearRect(0, 0, this.size.x, this.size.y);
+        for (var i = 0, length = this.offsetIndex; i &lt; length; ++i)
+            this.objects[i].draw(context);
+    },
+
+    complexity: function()
+    {
+        return this.offsetIndex;
</ins><span class="cx">     }
</span><span class="cx"> });
</span></span></pre></div>
<a id="trunkPerformanceTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/ChangeLog (196295 => 196296)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/ChangeLog        2016-02-09 03:30:42 UTC (rev 196295)
+++ trunk/PerformanceTests/ChangeLog        2016-02-09 03:30:44 UTC (rev 196296)
</span><span class="lines">@@ -1,5 +1,35 @@
</span><span class="cx"> 2016-02-07  Jon Lee  &lt;jonlee@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Tests: reuse objects already made.
+
+        Avoid thrash of object creation and removal by maintaining an index that
+        moves along the array as the adjust values change. If the tune value
+        requires more objects than the maximum size of the object array, then create
+        new objects. This means that the object array size never decreases.
+
+        * Animometer/tests/master/resources/canvas-stage.js: Maintain a separate
+        offsetIndex. For these tests, we want to avoid drawing the oldest objects,
+        so the scene will draw the object at offsetIndex to the end of the array.
+        (tune): Reverse the logic since &quot;removal&quot; of objects is much simpler and
+        involves simply changing the offsetIndex.
+        (animate): Update the for loop to draw from offsetIndex to the end.
+        (complexity): Update the definition.
+        * Animometer/tests/master/resources/canvas-tests.js: Maintain a separate
+        offsetIndex. For these tests, we want to avoid drawing the newest objects,
+        so the scene will draw the object at index 0 to the object at offsetIndex.
+        (SimpleCanvasStage.animate): Fly-by removal of local stage variable,
+        which is unneeded. Update the for loop to draw from offsetIndex to the end.
+        * Animometer/tests/simple/resources/simple-canvas-paths.js:
+        (SimpleCanvasStage.animate): Update the for loop to draw from 0 to
+        offsetIndex.
+        * Animometer/tests/simple/resources/simple-canvas.js:
+        (tune): Update logic. Here, offsetIndex represents the boundary of the last
+        index to render.
+        (animate): Update the for loop to draw from 0 to offsetIndex.
+        (complexity): Update the definition.
+
+2016-02-07  Jon Lee  &lt;jonlee@apple.com&gt;
+
</ins><span class="cx">         Tests: refactor and update styles.
</span><span class="cx"> 
</span><span class="cx">         * Animometer/tests/resources/main.js: Add helper methods that return
</span></span></pre>
</div>
</div>

</body>
</html>