<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Calypso88 &#187; AS3 Speed Benchmarking</title>
	<atom:link href="http://www.calypso88.com/?feed=rss2&#038;cat=7" rel="self" type="application/rss+xml" />
	<link>http://www.calypso88.com</link>
	<description>ActionScript trials &#38; tribulations.</description>
	<lastBuildDate>Sun, 07 Feb 2010 22:21:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>Updated benchmarks: Flash 10 Release Player</title>
		<link>http://www.calypso88.com/?p=539</link>
		<comments>http://www.calypso88.com/?p=539#comments</comments>
		<pubDate>Sun, 07 Feb 2010 22:04:48 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[AS3 Speed Benchmarking]]></category>
		<category><![CDATA[Actionscript 3.0]]></category>
		<category><![CDATA[Optimization]]></category>
		<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Speed Benchmarks]]></category>

		<guid isPermaLink="false">http://www.calypso88.com/?p=539</guid>
		<description><![CDATA[Since I had my benchmark code already warmed up from Friday and a photoshop doc open with my histograms, I figured I should make good on the updated speed tests that I promised a year ago. Here is basic math, receiving a huge boost between debug and release modes. The shaded bar is the duration [...]]]></description>
			<content:encoded><![CDATA[<p>Since I had my benchmark code already warmed up from Friday and a photoshop doc open with my histograms, I figured I should make good on the updated speed tests that <a href="http://www.calypso88.com/?p=174#comments">I promised</a> a year ago.</p>
<p>Here is basic math, receiving a huge boost between debug and release modes. The shaded bar is the duration of the call, so shorter means faster execution.</p>
<p><img src="http://www.calypso88.com/wp-content/uploads/2010/02/math_img1.gif" alt="speed benchmark: actionscript math operators" /></p>
<p>From here down, everything is running 10m iterations. The scale of these graphs is 560ms. Here's the difference in calling a static public variable, versus a local copy of same.</p>
<p><img src="http://www.calypso88.com/wp-content/uploads/2010/02/pi.gif" alt="speed benchmark: actionscript local var vs static public var" /></p>
<p>Finally, replacing the Math helper methods with some logic and basic math:</p>
<p><img src="http://www.calypso88.com/wp-content/uploads/2010/02/pow2.gif" alt="speed benchmark: actionscript math.pow squared" /><br />
<img src="http://www.calypso88.com/wp-content/uploads/2010/02/pow3.gif" alt="speed benchmark: actionscript math.pow cubed" /><br />
<img src="http://www.calypso88.com/wp-content/uploads/2010/02/min.gif" alt="speed benchmark: actionscript math.min" /><br />
<img src="http://www.calypso88.com/wp-content/uploads/2010/02/max.gif" alt="speed benchmark: actionscript math.max" /><br />
<img src="http://www.calypso88.com/wp-content/uploads/2010/02/abs.gif" alt="speed benchmark: actionscript math.abs" /><br />
<img src="http://www.calypso88.com/wp-content/uploads/2010/02/floor.gif" alt="speed benchmark: actionscript math.floor" /><br />
<img src="http://www.calypso88.com/wp-content/uploads/2010/02/ceil.gif" alt="speed benchmark: actionscript math.ceil" /><br />
<img src="http://www.calypso88.com/wp-content/uploads/2010/02/round.gif" alt="speed benchmark: actionscript math.round" /></p>
<p>These stack up pretty well with what I saw in the debug player <a href="http://www.calypso88.com/?p=174">a year ago</a> (although there is an overall speed increase in all the tests).</p>
<p>If anyone is curious, there is a slowdown in calculating powers of a number (i * i * i * i) as you have to reference that variable over and over - for me the break-even between stringing on more 'i's and just calling Math.pow() was around 60.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.calypso88.com/?feed=rss2&amp;p=539</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>AS3 Math Optimization &#8211; Math.random()</title>
		<link>http://www.calypso88.com/?p=524</link>
		<comments>http://www.calypso88.com/?p=524#comments</comments>
		<pubDate>Sat, 06 Feb 2010 07:37:55 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[AS3 Speed Benchmarking]]></category>
		<category><![CDATA[Actionscript 3.0]]></category>
		<category><![CDATA[Optimization]]></category>
		<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Random Number Generator]]></category>

		<guid isPermaLink="false">http://www.calypso88.com/?p=524</guid>
		<description><![CDATA[I was messing around with some bitmap code this evening and I came across a performance bottleneck with some repeated calls to Math.random(). Since I haven't posted anything in a while, I decided to do some benchmarking and try out an alternate (psuedo) random number generator. I chose the XOR algorithm, primarily because AS3 is [...]]]></description>
			<content:encoded><![CDATA[<p>I was messing around with some bitmap code this evening and I came across a performance bottleneck with some repeated calls to Math.random(). Since I haven't posted anything in a while, I decided to do some benchmarking and try out an alternate (psuedo) random number generator.</p>
<p>I chose the <a href="http://en.wikipedia.org/wiki/Xorshift" target="_blank">XOR algorithm</a>, primarily because AS3 is lightning-quick with bit operations, and the algorithm is only 4 lines of code. Here are two versions I tried:</p>
<p><code>
<pre class="actionscript"><ol><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; "><span style="color: #666666;">//  UINT</span></div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; ">&nbsp;</div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; "><span style="color: #F7De2D;">const</span> MAX_RATIO:<span style="color: #FFFFFF;">Number</span> = <span style="color: #FFFFFF;">1</span> / uint.<span style="color: #FFFFFF;">MAX_VALUE</span>;</div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; "><span style="color: #F7De2D;">var</span> r:uint = <span style="color: #FFFFFF;">Math</span>.<span style="color: #FFFFFF;">random</span><span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span> * uint.<span style="color: #FFFFFF;">MAX_VALUE</span>;</div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; ">&nbsp;</div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; "><span style="color: #666666;">//  returns a number from 0 - 1</span></div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; "><span style="color: #FF5E00;"><span style="color: #FFFF00;">function</span> XORandom</span><span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span>:<span style="color: #FFFFFF;">Number</span><span style="color: #FFFFFF;">&#123;</span></div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; ">	r ^= <span style="color: #FFFFFF;">&#40;</span>r &lt;&lt; <span style="color: #FFFFFF;">21</span><span style="color: #FFFFFF;">&#41;</span>;</div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; ">	r ^= <span style="color: #FFFFFF;">&#40;</span>r &gt;&gt;&gt; <span style="color: #FFFFFF;">35</span><span style="color: #FFFFFF;">&#41;</span>;</div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; ">	r ^= <span style="color: #FFFFFF;">&#40;</span>r &lt;&lt; <span style="color: #FFFFFF;">4</span><span style="color: #FFFFFF;">&#41;</span>;</div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; ">	<span style="color: #F7De2D;">return</span> <span style="color: #FFFFFF;">&#40;</span>r * MAX_RATIO<span style="color: #FFFFFF;">&#41;</span>;</div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; "><span style="color: #FFFFFF;">&#125;</span></div></li></ol></pre>
<p></code></p>
<p><code>
<pre class="actionscript"><ol><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; "><span style="color: #666666;">//  INT</span></div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; ">&nbsp;</div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; "><span style="color: #F7De2D;">const</span> MAX_RATIO:<span style="color: #FFFFFF;">Number</span> = <span style="color: #FFFFFF;">1</span> / <span style="color: #FFFFFF;">int</span>.<span style="color: #FFFFFF;">MAX_VALUE</span>;</div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; "><span style="color: #F7De2D;">const</span> NEGA_MAX_RATIO:<span style="color: #FFFFFF;">Number</span> = -MAX_RATIO;</div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; "><span style="color: #F7De2D;">var</span> r:<span style="color: #FFFFFF;">int</span> = <span style="color: #FFFFFF;">Math</span>.<span style="color: #FFFFFF;">random</span><span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span> * <span style="color: #FFFFFF;">int</span>.<span style="color: #FFFFFF;">MAX_VALUE</span>;</div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; ">&nbsp;</div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; "><span style="color: #666666;">//  returns a number from 0 - 1</span></div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; "><span style="color: #666666;">//  comment out line 13 for -1 - 1</span></div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; "><span style="color: #FF5E00;"><span style="color: #FFFF00;">function</span> XORandom</span><span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span>:<span style="color: #FFFFFF;">Number</span><span style="color: #FFFFFF;">&#123;</span></div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; ">	r ^= <span style="color: #FFFFFF;">&#40;</span>r &lt;&lt; <span style="color: #FFFFFF;">21</span><span style="color: #FFFFFF;">&#41;</span>;</div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; ">	r ^= <span style="color: #FFFFFF;">&#40;</span>r &gt;&gt;&gt; <span style="color: #FFFFFF;">35</span><span style="color: #FFFFFF;">&#41;</span>;</div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; ">	r ^= <span style="color: #FFFFFF;">&#40;</span>r &lt;&lt; <span style="color: #FFFFFF;">4</span><span style="color: #FFFFFF;">&#41;</span>;</div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; ">	<span style="color: #F7De2D;">if</span><span style="color: #FFFFFF;">&#40;</span>r &lt; <span style="color: #FFFFFF;">0</span><span style="color: #FFFFFF;">&#41;</span> <span style="color: #F7De2D;">return</span> r * MAX_RATIO;</div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; ">	<span style="color: #F7De2D;">return</span> r * NEGA_MAX_RATIO;</div></li><li style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; color: white; font-weight: normal; font-style: normal;"><div style="font-family: Monaco, Lucida Console, Lucida, 'Courier New', Courier, monospace; font-weight: normal; "><span style="color: #FFFFFF;">&#125;</span></div></li></ol></pre>
<p></code></p>
<p>It's worth noting that this algorithm works from a seed number. For my purposes, picking one random seed and iterating is fine, but this function is predictable enough that you wouldn't want to use this method for crypto or anything where you'd want "very random" data sets. This also could be useful in some situations where you'd want to replay a set of random numbers - such as generating enemies or levels in a game and then creating a replay by saving the seed number.</p>
<p>For my benchmark, I ran 25 sets of 10 million iterations on each function, using the 10.0 release player in Safari.</p>
<p><img src="http://www.calypso88.com/wp-content/uploads/2010/02/random_bench.gif" alt="acctionscript math.random optimization" /></p>
<p>Interestingly, the logic to gate negative numbers in the signed-int version was enough to push it out quite a bit past the uint version. All told, the uint algorithm runs in just under one fourth the time it takes to call Math.random().</p>
<p>As always, <a href="http://en.wikipedia.org/wiki/Xorshift" target="_blank">Wikipedia</a> will tell you as much as you want to know about the ins and outs of this algorithm and how it stacks up against other generators. And, just for fun, here's a frequency graph of the output.</p>

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_random_1275344363"
			class="flashmovie"
			width="460"
			height="250">
	<param name="movie" value="/wp-content/uploads/2010/02/random.swf" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="/wp-content/uploads/2010/02/random.swf"
			name="fm_random_1275344363"
			width="460"
			height="250">
	<!--<![endif]-->
		
<p><a href="http://adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>

	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
]]></content:encoded>
			<wfw:commentRss>http://www.calypso88.com/?feed=rss2&amp;p=524</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>AS3 Math Optimization – int is the new floor()</title>
		<link>http://www.calypso88.com/?p=174</link>
		<comments>http://www.calypso88.com/?p=174#comments</comments>
		<pubDate>Thu, 23 Oct 2008 07:08:40 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[AS3 Speed Benchmarking]]></category>
		<category><![CDATA[Actionscript 3.0]]></category>
		<category><![CDATA[Optimization]]></category>

		<guid isPermaLink="false">http://www.calypso88.com/?p=174</guid>
		<description><![CDATA[UPDATE: The benchmarks on this thread were taken in the Flash 9 Debug player (which includes some crazy bloating) - I've posted an updated set of tests here using the Flash 10 Release player, which should give you a better picture of real-world savings for the majority of web users. In case you missed my [...]]]></description>
			<content:encoded><![CDATA[<p><span style="background:#EEE; display:block; color:#222; padding: 10px 10px 10px 10px; margin:10px 0px 0px 0px; border: 1px solid #CCD"><strong>UPDATE</strong>: The benchmarks on this thread were taken in the Flash 9 Debug player (which includes some crazy bloating) - I've posted <a href="http://www.calypso88.com/?p=539">an updated set of tests here</a> using the Flash 10 Release player, which should give you a better picture of real-world savings for the majority of web users.</span></p>
<p>In case you missed my <a href="http://www.calypso88.com/?p=130">earlier post</a>, I've had a raging Flash-on for optimization lately, and today I'm jumping into the <a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/index.html?Math.html&#038;">Math</a> class. But first! A little warmup with operators.</p>
<p>I've often heard that addition is fastest, followed by subtraction and multiplication, with division being the slowest but I'd never seen any proof so I threw together my own test:</p>
<p style="text-align:center"><img src="http://calypso88.com/wp-content/uploads/2008/10/math_img1.gif" /></p>
<p>Way to go subtraction, almost 12% faster than addition! Ok, on to the good stuff. From here on down I'm running 1,000,000 iterations per test, the same <a href="http://www.calypso88.com/?page_id=160">test code</a> I used previously, and compiling each test individually about five times (or until I'm satisfied with an average time).</p>
<p>Alright - the Math class. First and foremost this class holds some handy constants so my human meat-brain doesn't have to. The downside is that the AVM doesn't play well with static properties of other classes so there's a pretty significant slowdown. Instead, just retrieve the constant from Math once and store it in a locally scoped variable.</p>
<p><img src="http://calypso88.com/wp-content/uploads/2008/10/pi.gif" /></p>
<p>While a lot of the Math methods are invaluable (Math.atan2 == &hearts;), there are also a few that aren't as complex and slow your swf down unnecessarily. A big one that's easy to work around is the pow method – unless you're doing some heavy lifting with it, you'll see a good boost by keying out your formula by hand:</p>
<p><img src="http://calypso88.com/wp-content/uploads/2008/10/math_pow2.gif" /><br />
<img src="http://calypso88.com/wp-content/uploads/2008/10/math_pow3.gif" /></p>
<p>Or you can replace costly comparison calls with a little logic:</p>
<p><img src="http://calypso88.com/wp-content/uploads/2008/10/math_min.gif" /><br />
<img src="http://calypso88.com/wp-content/uploads/2008/10/math_max.gif" /><br />
<img src="http://calypso88.com/wp-content/uploads/2008/10/math_abs.gif" /></p>
<p>Going a step further, you can take advantage of int casting to shear off any significant digits to the right of the decimal.</p>
<p><img src="http://calypso88.com/wp-content/uploads/2008/10/math_floor.gif" /></p>
<p>By substituting int as a super fast round-down, it's an easy jump to true rounding:</p>
<p><img src="http://calypso88.com/wp-content/uploads/2008/10/math_round.gif" /></p>
<p><span style="background:#EEE; display:block; color:#222; padding: 10px 10px 10px 10px; margin:10px 0px 0px 0px; border: 1px solid #CCD"><strong>UPDATE</strong>: A lot of other people have posted that you can recreate Math.ceil() by using <code>int(i)+1</code>, which never rang true to me – it only works on non-integers. I finally came around to a fix using modulus:<br />&nbsp;<br /><code>(i % 1) ? int(i) + 1 : i;</code><br />&nbsp;<br />I don't have a fancy graph for this one but I benched it around 75% faster than Math.ceil. </span></p>
<p>My last trick is a monstrous, ugly, hack that I'm hiding over on <a href=http://www.calypso88.com/?page_id=21#fastsine>the code page</a>, it's an approximation for computing sine (which means you can also use it for co-sine by adding &pi;/2 radians). Interestingly, this method of calculating the sine of an angle is actually less efficient and less accurate than the built in method, but the lag from calling the static method pushes Math.sin over the top.</p>
<p><img src="http://calypso88.com/wp-content/uploads/2008/10/math_sin.gif" /></p>
<blockquote><p><strong>Next</strong>: I'm hoping to give arrays a little loving in the not too distant future...if I ever get some free time that is. In the meantime – steer clear of unshift!</p>
<p>
<p><strong>Further reading</strong>:<br /><a href="http://blog.joa-ebert.com/2008/04/26/actionscript-3-optimization-techniques/" target="_blank">Joa Ebert on optimization</a><br /><a href="http://osflash.org/as3_speed_optimizations" target="_blank">Speed tests over on OS Flash</a><br /><a href="http://lab.polygonal.de/2007/05/10/bitwise-gems-fast-integer-math/" target="_blank">Bitwise gems at Polygonal</a></p>
</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.calypso88.com/?feed=rss2&amp;p=174</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Loops!</title>
		<link>http://www.calypso88.com/?p=130</link>
		<comments>http://www.calypso88.com/?p=130#comments</comments>
		<pubDate>Sat, 04 Oct 2008 04:52:25 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[AS3 Speed Benchmarking]]></category>
		<category><![CDATA[Actionscript 3.0]]></category>
		<category><![CDATA[Optimization]]></category>

		<guid isPermaLink="false">http://www.calypso88.com/?p=130</guid>
		<description><![CDATA[I've been thinking about AS3 optimization lately so I dusted off the old benchmark code and started speed testing some things. I meant to put together a post filled with exciting optimizations and tricks, but I got bogged down almost immediately in loop code. When I started getting into it, I was somewhat surprised by [...]]]></description>
			<content:encoded><![CDATA[<p>I've been thinking about AS3 optimization lately so I dusted off the old <a href="http://www.calypso88.com/?page_id=160">benchmark code</a> and started speed testing some things. I meant to put together a post filled with exciting optimizations and tricks, but I got bogged down almost immediately in loop code.</p>
<p>When I started getting into it, I was somewhat surprised by how many ways there are to write a basic <em>for</em> loop. Combined with the different number types, that grows into a huge amount of variation in the way people can write code, so it follows that some methods must be better than others. I broke it down into four different structures:</p>
<ol>
<li>Undefined variable, count up to ten.</li>
<li>Variable set to 10, negative increment to zero.</li>
<li>Variable set to 0, increment to ten.</li>
<li>Variable set to 10, decrement to zero.</li>
</ol>
<div>From there I also tested the three number types (Number, int, uint), as well as an untyped variable. And in the interest of full disclosure, I ran these loops exactly as they appear in a test harness set to iterate one million times. I compiled each test separately instead of running them in sequence just to make sure there was no weirdness from the garbage collector, and I ran each test at least three times (averaging them roughly in my head). The longest test clocked 660ms, the shortest was around 5. Here's the nitty-gritty:</div>
<p><img src="http://www.calypso88.com/wp-content/uploads/2008/10/loop-chart.gif" alt="" /></p>
<p>These results are a little odd…let's look at what's going on. First of all, the obvious one: int is fast, uint is slow, and untyped is downright painful. So int it is, now on to technique.</p>
<p>The first and third test appear to be the same code, but there's a pretty large discrepancy between them at runtime. In fact the first test always wins by a visible margin. <del>The difference between the first technique and the other three, is that the first test doesn't need an extra trip to memory to manually assign value to the newly instanced variable.</del></p>
<p>You may also be wondering about the negative increment in the second test – this is actually two tricks in one (and for a long time, I believed this to be the fastest execution). Even using a negative value, the addition operator takes about ¾ the time of the decrement (j--) operator. On top of that, looping backwards from a high value to zero, means you don't need to run a comparison, you can just cast the variable directly to a boolean.</p>
<p>All the rest of the code should be pretty pedestrian. There is one little snag in the untyped results but I suspect that's coming from weirdness in the JIT when it has to continually recast those values, and it's worth noting that uint really doesn't like the increment/decrement operators. And lastly, if you're wondering, I didn't test while loops here because both while and for loops are compiled into the same code – as far as the player is concerned, there is no difference, so use whichever you prefer.</p>
<p><span style="background:#EEE; display:block; color:#222; padding: 10px 10px 10px 10px; margin:10px 0px 0px 0px; border: 1px solid #CCD""><strong>UPDATE</strong>: Ok this is borked. In the middle of the night it came to me (in a vision?) – since the variable is never defined in the first test, maybe the JIT is just jumping the rails and never going through that loop at all? That would certainly explain the speed increase (better than my feeble explanation earlier).<br />&nbsp;<br />So testing should have been an easy iterator variable - testing a loop that counts to 10, over 1 million iterations should trace out 10 million. Somehow the undefined loop code is so extremely broken that it's actually leaking out into the scope above! When I tested I got back 10...implying that the test code actually broke my benchmark harness. I'm still trying to get to the bottom of this but in the meantime, just go with method #2.</span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.calypso88.com/?feed=rss2&amp;p=130</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
