« FlashLite: コードサイズが小さいActionScript | メイン | Flash: コールスタック »

FlashLite: バイトコードもいじってコードサイズを減らす

コードサイズ節約ねたの続きです。 アクションスクリプトの工夫だけではどうにもならない場合に、SWFのバイトコードを書き換えるような最適化をすればさらにコードサイズを節約できることもあります。 SWFのバイトコードを書き換えるには、perlのSWF::Parserやflasmを使う方法があるようです。私はSWF::Parserに付属しているdumpswf.plxを使うことが多いです。 バイトコードを書き換えるような最適化には、たとえば以下のようなものがあります。

交換法則とまとめpushのあわせ技

i + 2 よりも、2 + iのほうがまとめpushしやすくなります。
i = i + 2;の例です。
最適化前(21 bytes):
                96 03 00 00 69 00 96 03 00 00 69 00
                1C 96 03 00 00 32 00 0A 1D
まとめpush適用(18 bytes):
                96 06 00 00 69 00 00 69 00 1C 96 03
                00 00 32 00 0A 1D
2+iとしてまとめpush(15 bytes):
                96 09 00 00 69 00 00 32 00 00 69 00
                1C 0A 1D

Increment/Decrementを使う

±3までなら、足し算・引き算は、+1、-1を行う命令を使うほうがお得です。 上のi = i + 2の例で、Increment命令(0x50)を使うと以下のように12 bytesになります。
96 06 00 00 69 00 00 69 00 1C 50 50 1D

Duplicateを使う

同じ文字がたくさん並んだ文字列を作りたいなら、スタックトップを複製するDuplicate命令(0x4C)が使える場合があります。 Aが123回連続する文字列をxに代入したいなら、このように書けます。
96 09 00 00 78 00 00 41 41 41 41 00
4C 21 4C 21 4C 21 4C 21 4C 21 96 08
00 00 31 00 00 31 32 33 00 15 1D
赤い部分でAが128文字続く文字列を作ってます。やっていることを、アクションスクリプトで無理やり書くとこんな感じです。
tmp4 = "AAAA";
tmp8 = tmp4 add tmp4;
tmp16 = tmp8 add tmp8;
tmp32 = tmp16 add tmp16;
tmp64 = tmp32 add tmp32;
x = substring(tmp64 add tmp64, 1, 123);

まとめ

スタックに値を積む処理は、値の長さが小さいとヘッダの部分が3バイトあるのが気になります。Increment, DecrementやDuplicateをうまく組み合わせて使うことで、スタックに値を積む回数を減らすことができるので、これがコードサイズの節約につながります。

トラックバック

このエントリーのトラックバックURL:
http://labs.cybozu.co.jp/cgi-bin/mt-admin/mt-tbp.cgi/1340

コメント

FL1.1 でも increment とか使えるんですね。
(i-mode HTML シミュレータII 調べ)
SWF4 相当だから使えないと思ってました。

FL1.1 で使用できる命令の一覧って
どこかにないんでしょうか ?

コメントを投稿