Maps With Int Keys: Array vs. Dictionary
Behind the scenes Array holds its values in two ways: a densely-packed array at the beginning and a sparsely-packed map after that. This means it can be used as a map where the keys are indexes and not take up a huge amount of wasted space. Dictionary can also have int keys. Which is faster? Today we’ll find out!
This is a performance test to read and write to Array and Dictionary with int keys:
package { import flash.display.*; import flash.utils.*; import flash.text.*; public class ArrayVsDictionary extends Sprite { private var __logger:TextField = new TextField(); private function row(...cols): void { __logger.appendText(cols.join(",")+"\n"); } public function ArrayVsDictionary() { stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; __logger.autoSize = TextFieldAutoSize.LEFT; addChild(__logger); init(); } private function init(): void { var beforeTime:int; var afterTime:int; var i:int; var REPS:int = 10000000; var array:Array = new Array(); var dictionary:Dictionary = new Dictionary(); var j:int; row("Class", "Time"); beforeTime = getTimer(); for (i = REPS-1; i >= 0; --i) { array[i] = i; } afterTime = getTimer(); row("Array (write)", (afterTime-beforeTime)); beforeTime = getTimer(); for (i = REPS-1; i >= 0; --i) { dictionary[i] = i; } afterTime = getTimer(); row("Dictionary (write)", (afterTime-beforeTime)); beforeTime = getTimer(); for (i = REPS-1; i >= 0; --i) { j = array[i]; } afterTime = getTimer(); row("Array (read)", (afterTime-beforeTime)); beforeTime = getTimer(); for (i = REPS-1; i >= 0; --i) { j = dictionary[i]; } afterTime = getTimer(); row("Dictionary (read)", (afterTime-beforeTime)); } } }
I ran this test app in the following environment:
- Flex SDK (MXMLC) 4.6.0.23201, compiling in release mode (no debugging or verbose stack traces)
- Release version of Flash Player 11.4.402.265
- 2.3 Ghz Intel Core i7
- Mac OS X 10.8.1
And here are the results I got:
| Class | Time |
|---|---|
| Array (write) | 403 |
| Dictionary (write) | 708 |
| Array (read) | 97 |
| Dictionary (read) | 305 |

Array is the clear winner here: about 2x faster for writing and 3x faster for reading! This will get even better if you stick to the dense portion (generally the front) of the Array, but even in a completely sparse way you’re still going to beat Dictionary hands-down.
Spot a bug? Have a suggestion? Post a comment!
#1 by Joran on September 10th, 2012 ·
One thing that I’ve noticed using arrays like this was a really weird and annoying bug in flash that forced me to use a dictionary.
What happened was this: I had an array that I used as a map to set items in. Let’s start with this situation:
Then fore some reason, when I deleted the value for index 2 (to make it null) this happened:
Index 1 became undefined for no reason at all. Problem was that my for each loop broke because undefined is a value it iterates trough.
Come to think about it, I should have used if(value == undefined) instead of switching to a dictionary…
#2 by Pavel on September 10th, 2012 ·
@Joran
full example please?
*damn it, missed the “Reply”*
#3 by Pavel on September 10th, 2012 ·
@Joran
full example please?
#4 by skyboy on September 25th, 2012 ·
Though, Adobe’s Arrays are a bit stupid when migrating between sparse/dense. Once you pass a threshold to qualify the Array as sparse, it isn’t converted back to dense unless you set/reduce its length to 0 (special code handles this, resetting the entire object). Accidentally making an Array sparse permanently impacts performance of that Array.
#5 by jackson on September 25th, 2012 ·
Sounds disastrous. Any idea where the threshold is? Any tests to show the effect?
#6 by skyboy on September 25th, 2012 ·
The minimum sparse index is defined as 32. If there are 2^32 elements or more, any index is not an int, or less than half of the dense array is actually occupied, from the first non-undefined element to the last non-undefined element (starting index for the dense array portion can be higher than 0); nulls count, then it is converted to sparse.
One possible test would be to define an array of 1000 elements, set each to null, then starting at index 1 and going to index 600 use the delete statement on each element. Iterating over the array several times in each state should show the difference between sparse/dense.
http://hg.mozilla.org/tamarin-redux/file/3fc566f3a8b3/core/ArrayObject.cpp#l112
#7 by skyboy on September 25th, 2012 ·
Er. My bad, when less than 1/4th of the dense portion is occupied. Indexes from 1 to 800.