まじめに最適化を考える

ある機能に限定して高速化をすると、その機能を使うソフトに限定して高速化される。
ボトルネックを解消するのは正しいアプローチだが、仕様の変更や追加が伴うなら、その機能がどれだけ使われるのかという分析が前提である。
仕様の変更も機能の追加もしないで、単純に高速化されるのなら、それは高速化の程度や作業負荷にもよるが、おいしい話だ。


たとえば、DXRubyの描画機能は現在、メモリを確保して各種データを保存、そのアドレスをスプライトポインタ配列に突っ込む。
描画時にまずz指定をもとにソートして、はじめから順にデータを参照してD3DXSpriteに登録していく。
描画し終えたら確保したメモリは開放する。


もっとも簡単にちょっとだけ最適化する方法は、zを構造体の先頭に移動することだ。
スプライト構造体の中で一番参照されるのはzだから、ポインタ配列からアドレスを出しただけで参照できれば、オフセットを足す必要がなくなる。
また、メモリの確保と開放を省くなら、ある程度のメモリを確保しといて、そこにスプライト構造体を登録順に入れて、ポインタは今までどおりポインタ配列に入れておくようにする。
ソートするときは構造体をメモリコピーして入れ替えたりしないで、ポインタ配列だけ入れ替えればいい。
スプライト構造体配列が足りなくなったらreallocすることになるが、これは一瞬だけの負荷ということで諦める。
このあたりは、D3DXSpriteの内部でも同じことをやっていて2重管理になっているから、それを使うのをやめてオレオレSpriteを作りこめば効率がよくなる。
ソートの方式はシェーカーソートを使っているが、これはバブルソートの改良型だ。
ゲームのキャラ描画なら、普通は似たものをまとめて描画するから、z指定は同じ数字が並びやすいことが想像できる。
シェーカーソートはそういうデータに対して効率がよくなる傾向があって、実装も簡単だし、というわけで選んだのだが、もっといい方法があるかもしれない。


Imageオブジェクトに対する書き込みなどは適当に作ったから非常に遅い。
リアルタイムにいじることは少ないだろうから優先順位は低いかもしれないが、この部分を最適化することはボトルネックを解消することにつながる。
描画以外なら、音まわりはAPIたたくしかしていないからどーにもならないが、入力系は無駄が多い。
基本的に、とにかく実装することを優先したから、中身をいじるのはこれからの課題だ。


っていうか、実行速度うんぬんを語るなら、そんなことを考える前にRuby1.9系に対応するのが先だと思う。
とりあえずやってはみたけど、なぜかうまくコンパイルできないのよねー。
ただいま盛大に挫折中。
ライトユーザーである俺にとっては、こういうのは恐ろしく難しいことなのだ。