読者です 読者をやめる 読者になる 読者になる

ActionScript3 (mxmlc) でのコンパイルを100倍速にする方法

三日前から Flex2 SDK で ActionScript3 を始めました secondlife です。こんにちわ。AS3 は言語仕様的には ECMAScriptJava をあわせた感じで普通な書き方で OOP できるのでうーん、と頭をひねることはあまりないのですが、他のところでいろいろはまりまくってます。
で、原始的な解決方法として trace() を使ったプリントデバッグを行っているのですが、スクリプト言語に慣れきった体ではコンパイル時間が遅くて死にそうです。たとえばこんな HelloWorld.as

package {
    import flash.display.Sprite;
    public class HelloWorld extends Sprite {
        public function HelloWorld() {
            trace("Hello World!");
        }
    }
}

をコンパイルすると

$ time mxmlc HelloWorld.as
Loading configuration file /home/gorou/local/flex2/frameworks/flex-config.xml
/home/gorou/tmp/flex2/HelloWorld.swf (576 bytes)
mxmlc HelloWorld.as  3.59s user 2.77s system 98% cpu 6.456 total

とうちのマシンでは6秒半もかかってしまいます。一行変更してコンパイルでこんなに時間がかかっては、AS3 がほとんど解ってない体にはきついです。ということをぼやいていたら id:koyachi さんに fcsh 使うと速くなるということを教えていただきました。
http://labs.adobe.com/wiki/index.php/Flex_Compiler_Shell
からファイルを落としてきて、Flex2 SDK の展開したディレクトリに必要ファイルをコピるだけで fcsh が使えるようになります。下の例では readline が使えないので rlwrap でラップして使い勝手を向上させてますが、rlwrap コマンドを指定しなくてももちろん起動します。

$ rlwrap fcsh
Adobe Flex Compiler SHell (fcsh)
Version 2.0.1 build 155542
Copyright (c) 2004-2006 Adobe Systems, Inc. All rights reserved.

(fcsh)

で、早速コンパイルしてみます。

(fcsh) mxmlc -benchmark=true HelloWorld.as
fcsh: Assigned 1 as the compile target id
Loading configuration file /home/gorou/local/flex2/frameworks/flex-config.xml
Initial setup: 797ms
Loaded 8 SWCs: 1591ms
Files: 51 Time: 1688ms
Linking... 113ms
Optimizing... 78ms
SWF Encoding... 44ms
/home/gorou/tmp/flex2/HelloWorld.swf (576 bytes)
Total time: 4363ms
Peak memory usage: 32 MB (Heap: 13, Non-Heap: 19)

おー。初回コンパイルだけでも4秒強と短くなってますが、1回しか実行してないので誤差の範囲かもしれません。
で、ここからがすごくて、一度 fcsh 上で mxmlc コマンドでコンパイルしたファイルはメモリ上で展開されて次回からはちょっぱやにコンパイルしてくれるらしい*1です。
で HelloWorld.as にちょっと変更して、今度は先ほど mxmlc でコンパイルして返却された id (Assigned 1 as the compile target id) をつけて、compile コマンドでコンパイルすると

(fcsh) compile 1
Loading configuration file /home/gorou/local/flex2/frameworks/flex-config.xml
Initial setup: 28ms
Loaded 8 SWCs: 68ms
Recompile: /home/gorou/tmp/flex2/HelloWorld.as
Reason: The source file or one of the included files has been updated.
Files changed: 1 Files affected: 0
Files: 51 Time: 104ms
Total time: 202ms
Peak memory usage: 33 MB (Heap: 14, Non-Heap: 19)
Linking... 12ms
Optimizing... 26ms
SWF Encoding... 3ms
/home/gorou/tmp/flex2/HelloWorld.swf (580 bytes)
Total time: 43ms
Peak memory usage: 33 MB (Heap: 14, Non-Heap: 19)

おおお、43ms、先ほどの100倍速ですね!ちょうはやいよこれ三日前に知っていたら…、という感じです。というわけで、これからは fsch でコンパイルが当たり前になりそうです。というかこの速度を味わってしまうとこれ無しではやってられないと思います。
なお、Flex2 Builder ではこの方式でコンパイルしているらしいので、Flex2 Builder を購入してる eclipse 大好きな開発者の人はすでに恩恵を受けているみたいです。

Flex Builder では既にこの形の最適化が採用されています。

http://weblogs.macromedia.com/akamijo/archives/2007/01/flex_ant_tasks.cfm

この情報も id:koyachi さんに教えていただきました。ありがとうございます!!

*1:ひょっとしたら間違ってるかも