Array vs. Vector
Amazingly, I’ve never done a straight shootout between Vector and Array on this site. It’s a simple test, so read right on to see what kind of added performance you can get by using Flash 10’s Vector.
Intro
First of all, a little game. Ask yourself four questions before you read on to the performance results below:
- How much faster is Vector than Array when reading elements?
- How about when writing elements?
- What kind of performance speed up do you get by setting the Vector to a fixed-length?
- Is the speedup different on Mac compared to Windows?
Let’s look at the test that answers all these questions:
Test App
package { import flash.text.*; import flash.utils.*; import flash.display.*; public class ArrayVsVector extends Sprite { public function ArrayVsVector() { var logger:TextField = new TextField(); logger.autoSize = TextFieldAutoSize.LEFT; addChild(logger); function log(msg:*): void { logger.appendText(msg+"\n"); } const REPS:int = 1000; const SIZE:int = 100000; const VAL:int = 42; var i:int; var j:int; var temp:int; var beforeTime:int; var afterTime:int; var array:Array = new Array(SIZE); var vectorFixed:Vector.<int> = new Vector.<int>(SIZE, true); var vectorDynamic:Vector.<int> = new Vector.<int>(SIZE, false); for (i = 0; i < SIZE; ++i) { array[i] = VAL; vectorFixed[i] = VAL; vectorDynamic[i] = VAL; } log("Read:"); beforeTime = getTimer(); for (i = 0; i < REPS; ++i) { for (j = 0; j < SIZE; ++j) { temp = array[j]; } } afterTime = getTimer(); log("\tArray: " + (afterTime-beforeTime)); beforeTime = getTimer(); for (i = 0; i < REPS; ++i) { for (j = 0; j < SIZE; ++j) { temp = vectorFixed[j]; } } afterTime = getTimer(); log("\tVector (fixed): " + (afterTime-beforeTime)); beforeTime = getTimer(); for (i = 0; i < REPS; ++i) { for (j = 0; j < SIZE; ++j) { temp = vectorDynamic[j]; } } afterTime = getTimer(); log("\tVector (dynamic): " + (afterTime-beforeTime)); log("Write:"); beforeTime = getTimer(); for (i = 0; i < REPS; ++i) { for (j = 0; j < SIZE; ++j) { array[j] = VAL; } } afterTime = getTimer(); log("\tArray: " + (afterTime-beforeTime)); beforeTime = getTimer(); for (i = 0; i < REPS; ++i) { for (j = 0; j < SIZE; ++j) { vectorFixed[j] = VAL; } } afterTime = getTimer(); log("\tVector (fixed): " + (afterTime-beforeTime)); beforeTime = getTimer(); for (i = 0; i < REPS; ++i) { for (j = 0; j < SIZE; ++j) { vectorDynamic[j] = VAL; } } afterTime = getTimer(); log("\tVector (dynamic): " + (afterTime-beforeTime)); } } }
Performance Results
Now to check your assumptions with the performance results:
Environment | Array (read) | Vector (fixed, read) | Vector (dynamic, read) | Array (write) | Vector (fixed, write) | Vector (dynamic, write) |
---|---|---|---|---|---|---|
3.0 Ghz Intel Core 2 Duo, Windows XP | 835 | 599 | 595 | 1912 | 698 | 714 |
2.0 Ghz Intel Core 2 Duo, Mac OS X 10.5 | 1743 | 1083 | 1083 | 3390 | 1204 | 1221 |
Here are the speedups by percentage:
Environment | Array (read) | Vector (fixed, read) | Vector (dynamic, read) | Array (write) | Vector (fixed, write) | Vector (dynamic, write) |
---|---|---|---|---|---|---|
3.0 Ghz Intel Core 2 Duo, Windows XP | 39% | 40% | 174% | 168% | ||
2.0 Ghz Intel Core 2 Duo, Mac OS X 10.5 | 61% | 61% | 182% | 178% |
Performance Analysis
Now let’s revisit those questions:
- How much faster is Vector than Array when reading elements?
40% on Windows, 60% on Mac. - How about when writing elements?
170-180%. - What kind of performance speed up do you get by setting the Vector to a fixed-length?
None, sadly. - Is the speedup different on Mac compared to Windows?
Yes, the reading speedup is 50% greater on Mac than on Windows.
Conclusion
The Vector class yields a nice speedup where it counts: reading and writing elements. Aside from some quirky scenarios, you should always prefer Vectors over Arrays in performance-critical code. So, how’d you do on the little quiz? Sound off in the comments.
#1 by jpauclair on March 18th, 2010 ·
And what about deleting elements?
That’s the true bottle neck!
#2 by jackson on March 18th, 2010 ·
I’ve talked about that in this article with regards to Array, but never with regards to Vector. Maybe I’ll write a follow-up to this article with some more comparison tests.
#3 by Till Schneidereit on March 18th, 2010 ·
From your numbers, Vector reads are 61% faster than Array reads on a Mac, not 161%.
That’s still substantially more than the Windows speedup, of course, but much more in line of what one would expect.
#4 by jackson on March 18th, 2010 ·
Good catch! I’ve updated the post to fix this. Thanks for pointing it out.
#5 by Ramon Fritsch on March 19th, 2010 ·
I’ve got these results (Mac OS 10.6, 2.2Ghz):
Read:
Array: 2122
Vector (fixed): 1398
Vector (dynamic): 1392
Write:
Array: 3637
Vector (fixed): 1414
Vector (dynamic): 1412
cheers
#6 by jackson on March 19th, 2010 ·
Good to see your results confirm mine!
#7 by aaulia on March 21st, 2010 ·
You might to check using object instance as VAL instead of native type like int, Number, etc. My test using Bitmap as VAL, shows that array is slightly faster than Vector in writing (I didn’t test reading, etc).
#8 by jackson on March 21st, 2010 ·
I do seem to recall seeing that there are multiple implementations of Vector for various types. Perhaps my next article on the subject will cover the differences (or lack thereof) between them.
Thanks for the tip!
#9 by aaulia on March 21st, 2010 ·
You probably mean this ? http://code.google.com/p/polygonal/wiki/FlashPlayerContainerPerformance test by polygonal. His result confirm mine. For storing object (which is my need) array is faster.
#10 by jackson on March 22nd, 2010 ·
I hadn’t seen that data before, but it sure is interesting! I definitely need to do some more research into Vector‘s differences between types. Thanks for the link!
#11 by alekz on March 23rd, 2010 ·
Is everything alright with your percentage calculation?
You use different calculations for the percentage valuse for reading and writing elements.
I think you should decide to write for the speedup for the reading elements (fixed on win) either 39% or 139% and eaqualy for writing elements (fixed on win) either 174% or 274% !!
#12 by jackson on March 23rd, 2010 ·
Good catch! I was dropping the 1 for 1xx% values but not for 2xx% values. I’ve corrected the typo in the article. Thanks for pointing it out!
#13 by Aidan Fraser on March 30th, 2010 ·
“the reading speedup is four times greater on Mac than on Windows”??
I’d say it’s ~50% faster … (60 / 40 == 1.5)
#14 by jackson on March 30th, 2010 ·
Another remnant of the above percentage typos. Thanks for pointing this out!
#15 by Kevin on November 12th, 2010 ·
I’d like to see how an Array using the [ArrayElementType] metadata fares.
#16 by jackson on November 12th, 2010 ·
Interesting question. It turns out that the metadata is really only used by Flex for simple checking. Consider this:
The output is:
Which proves that the
Array
can indeed contain non-String
elements. Additionally, the compiler doesn’t give any warnings or errors. Check out the bytecode generated by MXMLC 4.1: (some editing by me)This is all the normal treatment of
Arrays
. Nowhere isstringArray
marked as having any particular type. Essentially, the metadata isn’t making its way past the compiler into the app and therefore the performance should be exactly the same as with any otherArray
.#17 by Kevin on November 14th, 2010 ·
That’s a great explanation. Thanks Jackson!
#18 by Kevin on June 27th, 2013 ·
It’s good to be very thorough on these tests, and check more real-world situations. For example, vectorDynamic[i] = new MovieClip() is ~45 % slower than array[i] = new MovieClip(), which in some circumstances can outweigh the benefits of using a vector. vectorFixed[i] = new MovieClip() is about 39% slower, which is barely better than the dynamic vector. I also found that reading properties from a MovieClip in a Vector takes 33% longer than reading properties from a MovieClip in an array. My write speed tests matched your results.
#19 by jackson on June 27th, 2013 ·
Check out the followup article for even more thorough results, especially using
Vector
to holdObject
andString
types. Also, keep in mind that performance can change dramatically between different Flash versions, hardware, operating system, compiling settings, etc. No doubt your testing environment is quite a bit different than the one I used when I wrote this article over three years ago. Lastly, when you’re allocating objects you’re involving a whole slew of code that’s unrelated to theVector
and therefore testing object allocation speed, VM, etc. It may be a real-world case, but it makes it hard to isolate where the CPU time is being spent.#20 by Pier on August 8th, 2013 ·
What about mobile?
Considering there are significant differences between Mac / Windows, it would be interesting to know what happens in iOS or Android.