## Dynamic Access: Part 1 (Indexing Arrays and Vectors)

Many classes in AS3 are dynamic, meaning that you can add and remove their fields at runtime. This is powerful, but extraordinarily slow. This series will cover some common ways you might be inadvertently using dynamic access or using it too much. This will help you make your code faster. In the first installation of the series, I’m going to talk about the simple act of indexing an array or vector.

The most common source of dynamic access comes in the form of using an array or vector. Try to count the number of dynamic accesses in the following code?

var a:Array = [1,2,3,4,5]; for (var i:int = 0; i < a.length; ++i) { if (a[i] > 0) { trace("element at " + i + " is positive: " + a[i]); } }

There are three array indexes per loop: checking the length field, indexing the i-th element for the comparison, and indexing the i-th element to print it. Since there are five elements in the array, the number of accesses is 15. In the general worst-case scenario where all elements are positive, there are 3*N dynamic accesses for an array of length N.

The above code is very slow for two reasons. First, the length is never changing in the loop and is therefore a loop invariant. It’s value should be cached. Second, the elements of the array are never changed, so the index should be cached as well. Here is a revised version:

var a:Array = [1,2,3,4,5]; var len:int = a.length; for (var i:int = 0; i < len; ++i) { var cur:int = a[i]; if (cur > 0) { trace("element at " + i + " is positive: " + cur); } }

This version cuts down the usage of the array to its minimal level. Here there is only one dynamic access per iteration so the general worst-case scenario is N+1 dynamic accesses. In code I’ve read it is very common to see the array indexing per loop repeated dozens of times. I cringe at every bit of code like that. Unless your code is operating on very small data sets or is allowed to run very slowly, there is no reason to not cache these dynamic accesses. I speak from personal experience that these accesses are so slow that you’d be better off doing huge amounts of calculations to avoid them. Your code could easily run faster doing a dozen arithmetic operations rather than one dynamic access.

One side effect of this slowness in the crucial array and vector classes is that many C-style optimizations become invalid. For example, look up tables are very often slower than just doing the computation over and over. Something as common as caching the values of Math.sin() and Math.cos() in the elements of a 360-element array results in code that is many times slower. You might think that using a vector would obviate this problem, but you’d only partially be right. All the proof you need is in Adobe’s documentation of the class to learn that it is indeed a dynamic class and therefore subject to the same slowdown as in the Array class. Empirical data indicates that only the actual reading and writing is any faster. The dynamic access remains.

#1 by Alec McEachran on September 16th, 2009 · | Quote

Jackson, we seem to be reading one another’s blogs today! You’ve got some interesting stuff.

Another aside: if precision is not an issue (and if it is why are you using Flash?) then sine and cosine approximation can be done very fast, though inline: http://bit.ly/5J9F5. I realise that this isn’t your point, but since you mention the Math.sin() and Math.cos() methods it’s a worthwhile cross-reference.