Steven Vachon

Benchmark: ActionScript 3 Vector vs. getChildAt

1 comment

I have never stored my particle instances in an array or any unique variables. There’s just no need to. The same can be achieved using only the child list, and with less bloat. New to Flash Player 10 is the Vector() class, and while they are faster than arrays, are they faster than getChildAt() and the child list? While being faced with a new particle-based project, I figured I’d find out.

Function Time Comparison
Vector() 3036.02ms (2.76% faster)
getChildAt() 3122.12ms

Keep in mind that adding Vector() to your code is an additional object and as such, will use additional memory.

Here is the benchmark code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package
{
	import flash.display.*;
	import flash.events.*;
	import flash.utils.*;
 
 
 
	public class VectorChild extends Sprite
	{
		protected var NUM_CHILDREN:int = 20000;
		protected var NUM_TESTS_EACH:int = 100;
 
		protected var containerTimes:Vector.<int> = new Vector.<int>(NUM_TESTS_EACH, NUM_CHILDREN);
		protected var testCount:int = -1;
		protected var testPhase:int = 0;	// 0=container, 1=vector
		protected var timer:Timer = new Timer(10, 1);
		protected var vectorTimes:Vector.<int> = new Vector.<int>(NUM_TESTS_EACH, NUM_CHILDREN);
 
 
 
		public function VectorChild()
		{
			startNextTest();
		}
 
 
 
		protected function getAverages():void
		{
			var containerSum:int;
			var vectorSum:int;
 
			for (var i:int=0; i<NUM_TESTS_EACH; i++)
			{
				containerSum += containerTimes[i];
				vectorSum += vectorTimes[i];
			}
 
			trace("===============================");
			trace("Average Container Test Time: "+ (containerSum/NUM_TESTS_EACH) +" ms");
			trace("Average Vector Test Time: "+ (vectorSum/NUM_TESTS_EACH) +" ms");
		}
 
 
 
		protected function handleContainerTest(event:Event):void
		{
			var time:int = getTimer();
 
			for (var i:int=0; i<NUM_CHILDREN; i++)
			{
				var sprite:Sprite = new Sprite();
 
				// Some nonsense
				sprite.x = Math.random() * 200;
				sprite.y = Math.random() * 150;
 
				addChild(sprite);
			}
 
			for (i=0; i<NUM_CHILDREN; i++)
			{
				sprite = getChildAt(i) as Sprite;
 
				// More nonsense
				sprite.x += 50;
			}
 
			time = getTimer() - time;
 
			containerTimes[testCount] = time;
 
			trace("Container Test: "+ time +" ms");
 
			reset();
			startNextTest();
		}
 
 
 
		protected function handleVectorTest(event:Event):void
		{
			var time:int = getTimer();
 
			var vector:Vector.<Sprite> = new Vector.<Sprite>(NUM_CHILDREN);
 
			for (var i:int=0; i<NUM_CHILDREN; i++)
			{
				var sprite:Sprite = new Sprite();
 
				// Some nonsense
				sprite.x = Math.random() * 200;
				sprite.y = Math.random() * 150;
 
				vector[i] = sprite;
 
				// Still gets added to the stage -- it needs to be visual, afterall
				addChild(sprite);
			}
 
			for (i=0; i<NUM_CHILDREN; i++)
			{
				sprite = vector[i];
 
				// More nonsense
				sprite.x += 50;
			}
 
			time = getTimer() - time;
 
			vectorTimes[testCount] = time;
 
			trace("Vector Test: "+ time +" ms");
 
			reset();
			startNextTest();
		}
 
 
 
		protected function reset():void
		{
			for (var i:int=NUM_CHILDREN-1; i>=0; i--)
			{
				removeChildAt(i);
			}
		}
 
 
 
		protected function startNextTest():void
		{
			if (++testCount >= NUM_TESTS_EACH)
			{
				if (testPhase == 0)
				{
					testCount = 0;
					testPhase = 1;
 
					timer.removeEventListener(TimerEvent.TIMER_COMPLETE, handleContainerTest);
 
					timer.addEventListener(TimerEvent.TIMER_COMPLETE, handleVectorTest);
 
					timer.start();
				}
				else
				{
					getAverages();
				}
			}
			else if (testCount == 0 && testPhase == 0)
			{
				timer.addEventListener(TimerEvent.TIMER_COMPLETE, handleContainerTest);
 
				timer.start();
			}
			else
			{
				timer.start();
			}
		}
	}
}


Comments

1 comment Jump to comment form

leef
1leef

Yes! I was just gearing up to test this myself, thanks for sharing your results Steven!

Top

Leave a Reply

Comments welcome! Name & email required; email always kept private. Please use basic markup. Wrap code with <code> tags.