久しぶりにテクニカルな話題。
Poderosaもそろそろ機能の追加は落ち着いたので、プロファイラにかけていくつかの目立って遅い箇所を高速化してみた。ちょっと粘って、起動時間は5~10%は短縮できたと思う。が、もともとの実行時間が、Poderosaのコード20%、.NET Framework内80%であるのでトータルの効果は出しにくい。それなりに努力したとはいえ、素手でカニを食うがごとく食べ残しが多いチューニングなわけですが。
でも、そのときに気づいた簡単な高速化技法があるのでちょっと書いてみる。既に知っている人も多そうなネタではあるけど。
public int Foo {
get {
return _foo;
}
set {
_foo = value;
}
}
みたいな単純なプロパティでも、実行時にはメソッドの呼び出しを行う。たとえ呼び出し元が
int a = t.Foo;
のようなものであっても。しかし、この場合動作上はフィールドをpublicにしてしまい、
int a = t._foo;
としても同じことだ。
メソッドの呼び出しではスタックフレームの伸張などもするから、プロセッサのインストラクション数ではフィールドアクセスと比べると局所的には10倍違ってもおかしくない。
このとき.NETのランタイムは、sealed宣言があるときに限り上のようなプロパティアクセスをフィールドアクセスと同様にJITコンパイルするようである。それぞれを比較して確かめたところ、クラスまたはメソッドがsealedのときのみ最適化されるようだ。
なので、特定のプロパティを数多く読み書きしているところでは"sealed"の追加は効果がある。もちろんこれがアプリケーションの動作全体のボトルネックになっているようなことは極めて稀にしても、プロパティアクセスはしょっちゅうあちこちでしていることだし、なにしろ"sealed"と一言追加するだけなのでお手軽かつ副作用もまずないのがポイント。
ちなみに使用したプロファイラはDevPartner Performance Analysis Community Edition。$500くらいだったら自腹で買ってもいいかなと思ったところ、他のあまり興味ないソフトウェアとのセットで$3105のセットしかなかった。さすがにそんなには出せん...バラ売りしてくれればいいのに。
仕方ないのでプロファイラは45日間のトライアル版があるので、その間に一通りのカタをつけることにした。
最近のコメント