Schemeをつくろう(19) GCの速度改善

GCの速度を改善してみる。改善したのは2箇所。

一度巡ったオブジェクトは巡らない

ルートは違うけど、参照を共有してる

ペア-+--+->数字
U    |  |  U
ペア-+  +->ペア-+->数字
N          U    |  U
                +->NULL

2個目のペアを巡る場合、参照先ににフラグが立っていれば、以降はフラグが立っている事が保障されるので、最初の1個と参照先だけ巡ればいい。


一度巡ったオブジェクトは巡らなくていい。


循環参照してる場合も、

ルート -> オブジェクト -> オブジェクト
              A               |
              |               V
          オブジェクト <- オブジェクト

フラグが立っていれば、以降を見る必要が無いので、途中で処理を中断できる。循環参照してても安心です。

スイープ&フラグ

前回は、スイープするときに、

元の状態

ペア->ペア->数字->数字->ペア->NULL
U     U     U     U     N

スイープ

ペア->ペア->数字->数字->NULL
U     U     U     U

と、Nのフラグのあるオブジェクトの破棄をするだけだった。


空で回すのはもったいないので、スイープ時にNのフラグを立てちゃえという作戦。

ペア->ペア->数字->数字->NULL
N     N     N     N

Nフラグを立てるフェーズは要らなくなるよね!!

あ、新規にオブジェクトを追加するときもNフラグを立てておく。繰り返し回数が減って速度アップ!

まとめ

2つの改善で大幅な速度改善ができました。単体のマーク・アンド・スイープではデータ量が増えると速度が落ちるという根本的な問題があるので、どう克服していくかが鍵となりそうです。


マークフェーズではは参照を全て見る。みたいなイメージがあったけど、データ個分だけ見ればいいんですね。勉強になりました。