H3XED

ActionScript 3: Array vs Vector Performance

Aug 2, 2012   Programming   Nick Vogt   Comments
Please note that this post is over a year old and may contain outdated information.
ActionScript 3With Flash version 10, Adobe added the Vector class, which is similar to an Array but more strict. Each Vector can only contain data of the same type and its data type must be declared during instantiation. I'm not going to go over the syntax to use Vectors in this post, but they are very similar to Arrays and have a lot of the same methods and properties.

For each of the tests I use a 200,000 iteration loop to get meaningful results. The loop itself has about 1ms of overhead, so keep that in mind when looking at the results. I also performed the tests with the Vector "fixed" property set to true, but it didn't change the results, so those tests are not shown.


Integer Operations


The first test is performing math operations with integers from the Array and Vector.

var i:int, test:int, startTime:int;
var testArray:Array = [15,28,99,36];
var testVector:Vector.<int> = new <int>[15,28,99,36];

test = 1;
startTime = getTimer();
for(i = 0; i < 200000; i ++)
{
   test+= testArray[0];
   test-= testArray[1];
   test*= testArray[2];
   test/= testArray[3];
   test+= testArray[0];
   test-= testArray[1];
   test*= testArray[2];
   test/= testArray[3];
}
trace(getTimer() - startTime); // 24 ms

test = 1;
startTime = getTimer();
for(i = 0; i < 200000; i ++)
{
   test+= testVector[0];
   test-= testVector[1];
   test*= testVector[2];
   test/= testVector[3];
   test+= testVector[0];
   test-= testVector[1];
   test*= testVector[2];
   test/= testVector[3];
}
trace(getTimer() - startTime); // 9 ms


Vectors are about 3 times faster here. Isolating just addition/subtraction or multiplication/division didn't affect the results much. My guess is that Arrays need to do extra type checking before performing the math operation, resulting in slower performance.


Number


The performance results for Numbers were strange.

var i:int, test:int, startTime:int;
var testArray:Array = [15.23, 28.43, 99.56, 36.87];
var testVector:Vector.<Number> = new <Number>[15.23, 28.43, 99.56, 36.87];

test = 1;
startTime = getTimer();
for(i = 0; i < 200000; i ++)
{
   test+= testArray[0];
   test-= testArray[1];
   test+= testArray[2];
   test-= testArray[3];
}
trace(getTimer() - startTime); // 31 ms

test = 1;
startTime = getTimer();
for(i = 0; i < 200000; i ++)
{
   test+= testVector[0];
   test-= testVector[1];
   test+= testVector[2];
   test-= testVector[3];
}
trace(getTimer() - startTime); // 7 ms


Like above, Vectors are over 3 times faster, but only when performing addition and subtraction. Unlike above, when doing multiplication and division, Arrays and Vectors perform the same:

var i:int, test:int, startTime:int;
var testArray:Array = [15.23, 28.43, 99.56, 36.87];
var testVector:Vector.<Number> = new <Number>[15.23, 28.43, 99.56, 36.87];

test = 1;
startTime = getTimer();
for(i = 0; i < 200000; i ++)
{
   test*= testArray[0];
   test/= testArray[1];
   test*= testArray[2];
   test/= testArray[3];
}
trace(getTimer() - startTime); // 8 ms

test = 1;
startTime = getTimer();
for(i = 0; i < 200000; i ++)
{
   test*= testVector[0];
   test/= testVector[1];
   test*= testVector[2];
   test/= testVector[3];
}
trace(getTimer() - startTime); // 8 ms



Strings


var i:int, startTime:int;
var testString:String;
var testArray:Array = ['Hello', 'World'];
var testVector:Vector.<String> = new <String>['Hello', 'World'];

startTime = getTimer();
for(i = 0; i < 200000; i ++)
{
   testString = testArray[0]+testArray[1];
   testString = testArray[0]+testArray[1];
   testString = testArray[0]+testArray[1];
   testString = testArray[0]+testArray[1];
   testString = testArray[0]+testArray[1];
}
trace(getTimer() - startTime); // 201 ms

startTime = getTimer();
for(i = 0; i < 200000; i ++)
{
   testString = testVector[0]+testVector[1];
   testString = testVector[0]+testVector[1];
   testString = testVector[0]+testVector[1];
   testString = testVector[0]+testVector[1];
   testString = testVector[0]+testVector[1];
}
trace(getTimer() - startTime); // 201 ms


Surprisingly there is no performance difference here for String concatenation.


Assigning References


Now assigning references from the Array and Vector. In this case Point objects.

var i:int, testPoint:Point, startTime:int;
var testArray:Array = [new Point(11,59), new Point(49,14)];
var testVector:Vector.<Point> = new <Point>[new Point(11,59), new Point(49,14)];

startTime = getTimer();
for(i = 0; i < 200000; i ++)
{
   testPoint = testArray[0];
   testPoint = testArray[1];
   testPoint = testArray[0];
   testPoint = testArray[1];
   testPoint = testArray[0];
   testPoint = testArray[1];
   testPoint = testArray[0];
   testPoint = testArray[1];
}
trace(getTimer() - startTime); // Array result: 14ms

startTime = getTimer();
for(i = 0; i < 200000; i ++)
{
   testPoint = testVector[0];
   testPoint = testVector[1];
   testPoint = testVector[0];
   testPoint = testVector[1];
   testPoint = testVector[0];
   testPoint = testVector[1];
   testPoint = testVector[0];
   testPoint = testVector[1];
}
trace(getTimer() - startTime); // Vector result: 12ms


The difference here was minor but consistent. Vectors are just slightly faster when assigning a reference to an object contained within. In games you will generally be assigning references to objects contained within lists before manipulating them, and this would indicate that Vectors are just slightly better for this.


Inserting and Removing Objects


The performance inconsistently went both directions here, so I wasn't able to get great results. On average the performance seemed similar between the Arrays and Vectors, regardless of whether I used the push, splice, or pop methods, or explicitly set index values.

One thing to keep in mind regarding inserting into and removing from an Array or Vector is that it is always faster to assign the next empty index explicitly, rather than use the push method. And using the pop method to remove from the end is faster than using splice or shift. Also, it is better to keep track of the Array or Vector length in a separate integer that you increment or decrement manually, rather than using the ".length" property.


Memory Usage


When instantiated empty, an Array takes up 76 bytes while a Vector takes up 56 to 60 bytes depending on the data type. When not instantiated (just a reference or pointer variable), they both take up 4 bytes. When containing the same amount of data, the Array and Vector generally have the same memory footprint though it can vary by 4 bytes in either direction. When storing Numbers, the Vector may take up noticeably more memory than the Array, likely because the Array is storing the data internally as integers if it can, while the Vector is strict in storing it as a Number. In ActionScript 3, a Number can be an integer or a floating point number, and it can be sometimes hard to tell just how Flash is storing it internally.


Final Thoughts


Vectors are faster in some situations, but in others there is little or no performance improvement. If there are no time sensitive tasks relying on your Array or Vector, the simpler syntax of the Array will make it the better choice usually. But if you are, for example, cycling through a large list of objects and assigning references every frame, the Vector will probably be the faster choice.
Share This Post
Twitter

Comments (0)

Share This Post
Twitter
H3XED © Nick Vogt   RSS   Policies   Twitter