Is there any performance benefit in storing Arrays in a Vector of type Array?
e.g Option 1
private var _arrays:Vector. = new Vector.<
I personally can't see any performance benefit. If there is any, it will be minimal. The whole point of having the vector class is to strictly type the elements of an array. But, an array object itself is designed to hold multiple types of objects or even untyped... so strictly typing a vector to an essentially untyped container that can be filled with untyped or multiple, variously typed contents... when thought out this way it just logically sounds like it will have little to no effect.
Update
Here's some performance test results to prove my point. We can see that when put under stress, the vector of arrays is equal to performance as an array of arrays, and in one test case, it's actually even worse:
/ =============================================================================================
Array Tests
============================================================================================= /
Testing Array of Arrays push performance:
Total time for 100000 push calls on Array of Arrays: 24
Testing Array of Arrays random assignment performance:
Total time for 100000 random assignment calls on Array of Arrays: 40
Testing Array of Arrays sequential read performance:
Total time for 100000 sequential read calls on Array of Arrays: 14
Testing Array of Arrays random read performance:
Total time for 100000 random read calls on Array of Arrays: 41
/ ============================================================================================= /
/ =============================================================================================
Vector Tests
============================================================================================= /
Testing Vector of Arrays push performance:
Total time for 100000 push calls on Vector of Arrays: 24
Testing Vector of Arrays random assignment performance:
Total time for 100000 random assignment calls on Vector of Arrays: 49
Testing Vector of Arrays sequential read performance:
Total time for 100000 sequential read calls on Vector of Arrays: 14
Testing Vector of Arrays random read performance:
Total time for 100000 random read calls on Vector of Arrays: 41
/ ============================================================================================= /
And the test code:
import flash.events.Event;
import flash.utils.getTimer;
//Performance timer related
var startTime:Number; //ms
//
//Our two container types we're testing IO on
var arrayOfArrays:Array = new Array();
var vectorOfArrays:Vector.<Array> = new Vector.<Array>();
//
//Used to store a bunch of arrays we're going to use to test
var testArrays:Array = new Array();
//
var randomIndex:uint = 0;
var i:uint = 0;
var arr:Array;
//Generate a bunch of arrays of mixed typed content
for(i = 0; i < 100000; ++i) {
generateTestArray();
}
/*======================================================================================================
*********************************** Array Tests *********************************************
*=====================================================================================================*/
//Test push on array of arrays
trace("Testing Array of Arrays push performance:");
startTime = getTimer();
for(i = 0; i < 100000; ++i) {
arrayOfArrays.push(testArrays[i]);
}
trace("Total time for 100000 push calls on Array of Arrays: " + (getTimer() - startTime));
trace(" ");
//
//Test random write on array of arrays
trace("Testing Array of Arrays random assignment performance:");
startTime = getTimer();
for(i = 0; i < 100000; ++i) {
randomIndex = Math.round(Math.random() * 99999) as uint;
arrayOfArrays[randomIndex] = testArrays[randomIndex];
}
trace("Total time for 100000 random assignment calls on Array of Arrays: " + (getTimer() - startTime));
trace(" ");
//
//Test sequential read on array of arrays
trace("Testing Array of Arrays sequential read performance:");
startTime = getTimer();
for(i = 0; i < 100000; ++i) {
arr = arrayOfArrays[i];
}
trace("Total time for 100000 sequential read calls on Array of Arrays: " + (getTimer() - startTime));
trace(" ");
//
//Test random read on array of arrays
trace("Testing Array of Arrays sequential read performance:");
startTime = getTimer();
for(i = 0; i < 100000; ++i) {
randomIndex = Math.round(Math.random() * 99999) as uint;
arr = arrayOfArrays[randomIndex];
}
trace("Total time for 100000 random read calls on Array of Arrays: " + (getTimer() - startTime));
trace(" ");
//
/*====================================================================================================*/
/*======================================================================================================
*********************************** Vector Tests *********************************************
*=====================================================================================================*/
//Test push on vector of arrays
trace("Testing Vector of Arrays push performance:");
startTime = getTimer();
for(i = 0; i < 100000; ++i) {
vectorOfArrays.push(testArrays[i]);
}
trace("Total time for 100000 push calls on Vector of Arrays: " + (getTimer() - startTime));
trace(" ");
//
//Test random write on vector of arrays
trace("Testing Vector of Arrays random assignment performance:");
startTime = getTimer();
for(i = 0; i < 100000; ++i) {
randomIndex = Math.round(Math.random() * 99999) as uint;
vectorOfArrays[randomIndex] = testArrays[randomIndex];
}
trace("Total time for 100000 random assignment calls on Vector of Arrays: " + (getTimer() - startTime));
trace(" ");
//
//Test sequential read on vector of arrays
trace("Testing Vector of Arrays sequential read performance:");
startTime = getTimer();
for(i = 0; i < 100000; ++i) {
arr = vectorOfArrays[i];
}
trace("Total time for 100000 sequential read calls on Vector of Arrays: " + (getTimer() - startTime));
trace(" ");
//
//Test random read on vector of arrays
trace("Testing Vector of Arrays sequential read performance:");
startTime = getTimer();
for(i = 0; i < 100000; ++i) {
randomIndex = Math.round(Math.random() * 99999) as uint;
arr = vectorOfArrays[randomIndex];
}
trace("Total time for 100000 random read calls on Vector of Arrays: " + (getTimer() - startTime));
trace(" ");
//
/*====================================================================================================*/
function generateTestArray():void
{
var newArray:Array = new Array();
var totalItems:uint = Math.round(Math.random() * 50 + 1);
var i:uint = 0;
var dice:uint = 0;
for(i; i < totalItems; ++i) {
dice = Math.round(Math.random() * 5);
switch(dice) {
case 0:
newArray.push(new int(Math.random()));
break;
case 1:
newArray.push(new String(Math.random()));
break;
case 2:
newArray.push(new Array());
break;
case 3:
newArray.push(new MovieClip());
break;
case 4:
newArray.push(new Date());
break;
case 5:
newArray.push(new Event(Event.COMPLETE, false, false));
break;
}
}
testArrays.push(newArray);
}
EDIT
My original answer was wrong except for the very last part, and I have to apologize for that. I knew for a fact that Vector has exactly four implementations "under the hood". (You can find decompiled sources from FP 10 playerglobal.swc in a post by Robert Penner here) Three of those are for number types (int, uint and Number). One is for Object types. This last one serves as a catch-all and takes in all classes derived from Object. This is why I assumed that Vector.<Object>
was still faster than Array, relying on the information regarding vectors and arrays available from Adobe.
However, it seems that this information is wrong, or at least it leaves out some important parts:
While Vector.<AnyClassDerivedFromObject>
allows for strict typing, this type information is only evaluated at compilation time (so you get more type safety), but not at runtime - thus essentially the benefits of strict typing object vectors do not apply to performance. See this blog post for more info.
Consequently, the only implementations of Vector that are faster than Array are the ones for number types (!).
In fact, I have done some extensive testing on this, and have come to the conclusion that while Vector.<int>
is up to 60% faster than Array of ints, all the derivates of Vector.<Object>
are not only equal in speed (i.e. Vector.<Object>
performs the same as Vector.<String>
, they also are about 20% slower than Array. I've double- and triple-checked this, so I believe the results to be fairly accurate.
It still is true that the number type vectors are faster, so you should use those for performance benefits over Array. But:
END EDIT
Only if you're going to use sort()
, sortOn()
or any other of the convenient sorting functions of Array, you might still decide otherwise, because these are native functions, and as such really fast. Implementing your own sorting methods on a Vector will probably not match their speed.