AlecMcE.com

Coding on the Flash Platform

Constants and Speed

View Comments

A common scenario in coding is to have a constant that you would like to be shared across classes. Defining the constant separately is bad because if you change the constant value in one class it does not get changed in another, and you’re likely to have a bad dose of debugging. However, defining a constant in an external class and referencing it when you need it is bad because it is really slow.

How Slow?

Using Grant Skinner’s Performance Harness I did a quick test to determine exactly how slow various mechanisms for referencing variables and constants actually are. The results are as follows (based on accessing the variable/constant 10,000,000 times!):

referencing a local variable 46.80 ms
referencing a member variable 44.00 ms
referencing a member constant 48.40 ms
referencing a static constant in the same class file 52.80 ms
referencing a package constant 526.00 ms
referencing an external static constant 550.00 ms

There isn’t a significant difference between the speed of access of member variables, local variables, or member constants. Perhaps a static constant in the same package is a little slower, but then it would only be defined as public static if it was referenced elsewhere as an external static constant, so it is inevitably a slow choice at some stage.

I tested package constants on the basis that this blog I came across suggested that I could get a performance saving by using package constants. This does not appear to be the case; or at least not significantly.

download the test source code

Yes, you probably know this already, perhaps with the expception of the package constant, which I had never considered before. However, I’d never done this test definitively and having recently come across Skinner’s test harness I thought I’d be thorough.

Suggested Solution

My technique for solving the dilemma of wanting a single source for constants but accessing them quickly is to create a static constant repository, but reference them into member constants in your speed critical classes, as follows:

A constants class:

package example
{
	public class Constants
	{
		public static const MY_CONSTANT:int = 100;
	}
}

A class that uses the constant, in time-critical code:

package another
{
	import example.Constants;

	public class TimeCritialCode
	{
		private const MY_CONSTANT:int = Constants.MY_CONSTANT;

		public function timeCriticalLoop():void
		{
			... important stuff referencing MY_CONSTANT ...
		}
	}
}

Written by alec

November 17th, 2009 at 11:48 am

Posted in as3, performance

  • Is this the mxml compiler's -define=etc... solution? Come on Jackson, don't tease us!
  • Of course the best way is to use a compile-time variable. I'll be covering that very soon on JacksonDunstan.com. You're totally right about the "refactorability" loss you get with direct constant usage. It's something I usually reserved for only the most performance-critical code... until I found compile-time constants of course!
  • I discount that because I'm considering the scenario where you need to share a constant across multiple classes. There were two clauses to consider: speed, and the ability to change the constant easily; 'refactorability'.

    You're welcome to do that by changing constants directly across a project Jackson, but rather you than me! :)
  • The handling of constants is indeed quite annoying. Your workaround is a pretty good alternative to redefining the variables everywhere. For even better speed though, you would eliminate the variable lookup and just use the constant directly. It's ugly but fast. Comments can help a little here. :)
  • I know it’s been done a million times, but I wanted to check for myself the speed of variable access in #as3: http://bit.ly/JWk0c


    This comment was originally posted on Twitter

blog comments powered by Disqus