§3.Garbage Collector




ガーベジコレクタというのは、確かに便利な機構である。ひとたび、Javaのようなガーベジコレクタ付きの言語を触れば、二度とC++に戻りたくないと思うかも知れない。そして、C#にも、ガーベジコレクタはついている。もちろん、Rubyにも!

これからの言語はガーベジコレクタが無ければ、生き残れないと言わんばかりだ。

Windows用のゲームを書くことを考えてみよう。Javaはnativeコードを生成することを設計思想として禁止(?)しているので、Javaで書くというのは、あまり現実的でない気がする。

Rubyは、インタプリタ式でガーベジまでやっていて、その上、変数の型が無いのでかなり遅い。リアルタイムのゲームを書くのは論外だろう。

現実的な選択肢は、おそらくC#かC++しか無いのだ。問題は、C#を用いて、C++に匹敵するスピードのソフトが書けるかということだ。

思うに、書けない。厳密にテストしたわけではないが、自分でガーベジを実装したことがあるので、容易に想像がつく。ガーベジがあると、倍ぐらい遅くなる。最適化をうまくやれば、もう少し早くなるかも知れないが。

ガーベジをマーク&スイープなどでやると、負荷が集中するので、ゲームに使うならばインクリメンタルで(=少しずつ)やるしかない。ついでに言うなら、世のなか、ガーベジの高速化には世代方式にすればいいとかいう意見が有力だったりして、Rubyでも世代方式のガーベジを実装した人がいるんだが、思ったより早くなかったらしい。そりゃそうだろう。Java系のコンパイラでも実装したことがあればすぐに気がつくと思うんだが、問題となるのは局所的に使われる小さなオブジェクトのガーベジ。これをどれだけ早いタイミングでガーベジできるかが高速化の鍵なのだ。だから、Pythonのように参照カウントつけて、0になれば破棄、それと同時に(循環参照しているオブジェクトはいつまでも0にはならないので)インクリメンタルマーク&スイープでガーベジという方法のほうが効率は良いだろう。

やねうらおは、別にガーベジを専門で研究しているわけではないので、これ以上深く立ち入ることはしない。まだまだ改良の余地のありそうな分野だ。将来的にグラフ理論とかの応用でスゴー(゚Д゚)なガーベジコレクタが提案されることを期待する。

話が脱線した。どうせゲームでは描画がメインで、描画はDirectXを呼ぶだけ!という人にとっては、C#がC++の倍ぐらい遅かろうと、描画が処理の8割か9割ぐらいを占めるんだから何ら問題がない。まあ、そういう言い方もできるだろう。

とりあえず、ガーベジについては、気が向いたら実装すると言う方向でいこう。いま目指すべきは、C++の上位互換の形で拡張することだ。既存のソースは流用できたほうがいいし、そのほうがシフトもしやすい。