Calendar

August 2016
Mo Tu We Th Fr Sa Su
<< >>
1234567
891011121314
15161718192021
22232425262728
293031

Langs

Flash 9 Optimizations

Posted on Mar 08 2008

The new virtual machine than can run AS3 and Haxe languages in the Flash Player 9 brings a lot of additional speed for many common operations. This is very good news for developers since you can now write more complex algorithms in Flash such as 3D or Physics engine with correct performances.

However, there are still several pitfalls since some operations are pretty slow when compared to others :

  • creating a new object is slow : if you have a lot of short living objects that are allocated frequently, it's better to create a "Allocator" class that will store a list of reusable instances.
  • calling a lot of methods is not so fast : when you have some small methods that are very often called, it's often faster to rewrite the code directly in the calling method. For example, given a Point class :
var p = new Point(4,5);

p.add(p2.x,p2.y);

p.x += p2.x;
p.y += p2.y;

This process of replacing a method call with the actual code is called inlining, and Haxe compiler has support for an inline keyword so that you can define which methods will be automatically inlined by the compiler when called (see Haxe Documentation)

  • accessing static vars and functions is slow : you can either create an instance and use instance variables and methods instead of static ones or use the Haxe inline keyword.
  • reading and writing into arrays is slow : this is very bad news. The only native data structure of Flash9 is painfully slow. It's a lot faster to access a typed instance field than to access an array. One way to optimize that is to create your own linked list :
class MyCell {
    public var elt : MyClass;
    public var next : MyCell;
    public function new( elt, next ) {
        this.elt = elt;
        this.next = next;
    }
}

class MyList {
    public var head : MyCell;
    public function new() {
        head = null;
    }
    
    public function add( elt : MyClass ) {
        head = new Cell(elt,head);
    }
}

var l : MyCell = mylist.head;
while( l != null ) {
    var e : MyClass = l.elt;
    
    l = l.next;
}

First, the good news : using a typed linked list is 2 to 3 times faster than using an Array ! (if you want to test that in AS3, make sure to type all your variables, the code here is entirely typed thanks to Haxe type-inference)

Now the bad news : you will have a define a MyList and MyCell class for each different class you want to store. So you have to copy/paste the same code again and again. Using Dynamic (or * in AS3) is out of question here since that would require a cast for each reading of an element that would be slow again.

Current Haxe users know that the language have typed arrays in order to ensure type-safety. You can also define your own parametrized classes, so it's pretty easy to write-once the following :

class Cell<T> {
    public var elt : T;
    public var next : Cell<T>;
    public function new( elt, next ) {
        this.elt = elt;
        this.next = next;
    }
}

class List<T> {
    public var head : Cell<T>;
    public function new() {
        head = null;
    }
    
    public function add( elt : T ) {
        head = new Cell(elt,head);
    }
}

The problem is that typed-parameters are only used for compile-time type checking. Since the Flash9 VM does not support them, they disappear in the compiled code and are then replaced by the AS3 * type, so all your accesses to the List will need an additional cast... we're back the problem.

Thinking about the problem, I was thinking then : why not let the compiler generate a specific version of the List class for each parameter it will be used ? This way it would generate a List_User and a Cell_User class that can contains User instances, and so on.... automatically at compile time !

That approach was proved quite easy to implement, so it works now in Haxe. In order to let the user choose between speed and codesize, the default Haxe List class has not been modified, but instead a new haxe.FastList class has been added (accessible when compiling for Flash9).

In order to create your own "generic" classes that will be specialized when used with a type parameter, you can simply have your class implements the haxe.rtti.Generic interface.

Both haxe.FastList and haxe.rtti.Generic are now on Haxe CVS (you can download and compile it to give it a try) and will be part of the 1.19 Release.

Conclusion

There's a lot of painful things to do when you want to optimize your code to run fast on Flash9. But thanks to Haxe inline and generics, it's a lot more easy to do while keeping your code clean and maintainable.

0 comment
Name : Email : Website : Message :