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