Monday, October 13, 2008

ActionScript Vector Performance

Flash Player 10 is coming out this month. This weekend I went to Adobe's FlashCamp. It was a lot of fun by the way, and a big thank you must go to Dom and the folks at Adobe for a great event. Adobe really treats developers well. Anyways, there are a lot of great new features in Flash Player 10. Other folks will talk about 3-d and text engines and Pixel Bender, etc. but me? I'm excited about Vectors.

If you are like me, then the first time you heard about the new Vector class in ActionScript, you thought it might have something to do with graphics and what not. However, I was overjoyed to learn that it was like the Vector from C++ and Java, i.e. a list-style collection. Like the Vector from the STL and in Java 1.5+, it is parameterized. Even better, you can specify a fixed length for it. In other words, you can say that is a collection that only allows one type of object and that there is fixed number of objects in it. This leads to excellent performance optimizations that are possible, and indeed Adobe has taken advantage of this. Of course I had to test this out for myself.

One of the other nice things about FlashCamp was that they gave us a new build of Flex Builder. This one has support for the new language features supported in Flash 10. To enable the new features, you just change the Flash Player version that you target and voila! I took some benchmark code that I had used for Flash/JS comparisons. Here is the original code:

private function testArray():Number{
var startTime:Date = new Date();
var arrStr:String = null;
var arr:Array = new Array();
var i:int=0;
for (i=0;i<=94;i++){
arr.push(i);
}
for (i=0;i<=arr.length;i++){
arr.push(arr.pop());
arr.sort().reverse();
arr.push(arr.splice(0,1));
}
arrStr = arr.join();
return (new Date()).getTime() - startTime.getTime(); }

And here is the new version that uses a Vector instead of an Array.

private function testVector():Number{
var startTime:Date = new Date();
var v:Vector.<int> = new Vector.<int>();
var arrStr:String = null;
var i:int = 0;
for (i=0;i<=94;i++){
v.push(i);
}
for (i=0;i<=v.length;i++){
v.push(v.pop());
v.sort(comp).reverse();
v.push(v.splice(0,1));
}
arrStr = v.join();
return (new Date()).getTime() - startTime.getTime(); }

Do you like the Vector syntax?

Anyways, back to the results. The Array averaged around 90 ms on my MacBook. The Vector code averaged around 20 ms on my MacBook. 4.5x? Very nice.

One thing I immediately wondered about Vector was if the Flash compiler erased the type. At first glance, there is no reason to do this. It is a different type, so there is no backwards compatibility issue. It does not extend Array, but it is a dynamic class. The documentation states that the push() method does not do type-checking at compile time, but does do this at runtime. This seemed weird, but it would imply that type information is not erased, since it can be checked against at runtime. However, in my testing I could use push() to push any object into any Vector, and had no compile time or runtime errors.

3 comments:

Anonymous said...

I'm very familiar with the term" Vector" from c++/stl, and years spent on my MS in Math.

What I don't understand why they would use the the name "Vector" in the context of flash/flex.

Why complicate/confuse terms. Searching for flex vector related info just got needlessly complicated.

Yuku said...

What is that 'comp' parameter?

Unknown said...

@yukuku Good catch. It is a comparator function for the sort. Most of Vector's syntax is copied from Array, but for sort it requires a comparator function (it is optional for Array.) In this case I called that function 'comp' and it just returns the difference in the elements, i.e. function comp(x:int, y:int):Number { return x-y; }