昨日は何となく新しい作業をする気になれなかったので、mugeneをプロファイルして最適化してみた。やったことは割と単純で、まずmono --profileを使って、実用的なMML(版権ものなので公開していないが9KBくらいのそれなりにでかいものがある)をコンパイルした結果を見る。それで処理時間が長いメソッドが何なのかに留意しつつ、メモリ使用量が一番大きい部分を見る。大抵は一番メモリを食っている部分を改善すれば高速化に繋がる。
すると、以前高速化のために導入したはずのC5.HashDictionaryが槍玉に挙がった。
最初は単にdictionaryインスタンスの過剰生産ということで、不要になったらクリアしてインスタンスを使い回すロジックにしたら、メモリ消費量が1/3程度になったのだけど、それでもまだC5が一番でかい。
プロファイルの結果をもとにC5のソースを眺めてみたら、hash tableのbuckets配列を毎回生成していた。bucketsは構造体かもしれないが配列はよろしくない。しかしどう最適化していいかいまひとつ分からなかったので、とりあえずC5.HashDictionaryをHashtableに置き換えて対処した。これでさらに40%メモリ使用量を削減できた。
中でKeyValuePairをobjectに取り出してboxingしているのがよろしくないが(そのためにgeneric dictionaryを導入したのだった)、まだこっちの方がマシ、という状態だった。
速度的にはコンパイル時間がだいたい半分に短縮されたので、とりあえず目先の問題は片付いたという感じだけど、本当はもう半分くらいにはしたい。ただ言語設計的にマクロ展開の嵐なので、これはもうどうしようもない気もしている。言語レベルで根本から設計しなおした方が良いのではないか、と思っているのだけど、なかなか手をつけられない。
Leave a comment