VisualWorks:パフォーマンスチューニング
2007/03/30 (Fri) 22:07:46 JST
インライン展開を利用する
clean block を使う
full / copying block は clean block よりもコンパイル時のバイトコードが増えます。ブロックに内でリターンを使わず、 self やブロック外の変数を参照しないようにすると clean block を作ることができます。
次の copying block の例を見てください。
| t | [ :x | t := x frobnicate ] value: 1. t := t * 2. ^ t 1 <D4 00> create array size 1 3 <4C> store local 0; pop 4 <10> push local 0 5 <FA 00 01> make copying block (1) 8 <4A> push 1 9 <DF 1A> no-check send value: 11 <66> pop 12 <D9 00> push local 0 at 0 14 <4B> push 2 15 <A8> send * 16 <DC 00> store local 0 at 0; pop 18 <D9 00> push local 0 at 0 20 <DE 01> outer(1) method return
ブロック外の変数 x を参照しているので copying block が生成されます。ブロック外の変数を copying block と共有する (shared array, 後述) 処理と、ブロック引数 (copied values) を渡すバイトコードが生成されます。
次のコードは、先ほどのコードを clean block になるように変更したものです。
| t | t := [ :x | x frobnicate ] value: 1. t := t * 2. ^ t 1 <1C> push BlockClosure [] in [] in UndefinedObject>>unboundMethod 2 <4A> push 1 3 <DF 1A> no-check send value: 5 <4C> store local 0; pop 6 <10> push local 0 7 <4B> push 2 8 <A8> send * 9 <4C> store local 0; pop 10 <10> push local 0 11 <DE 01> outer(1) method return
clean block は普通のオブジェクトへのメッセージ送信と同じ処理で済みますから、copying block と比べて処理ステップ数もバイトコード量も減ります。
ただし、この方法はVisualWorksにのみ効果があります。ブロックがクロージャではない (?BlockContextの) Squeakでは、以上のコードをコンパイルしてもほとんど差は出ません。
Inverse Pages: VisualWorks