Delegate

Sergey Ryazanovが書いたDelegateに関する記事を読んでみた。Don Clugstonが書いたDelegateに関する記事に対するものとして書いたらしい。

 Don Clugstonの記事の冒頭では、C++のmember関数ポインタの解説をしていて、C++のmember関数ポインタは世の中の色んなC++コンパイラ毎に実装は異なるけれど、実際にmember関数ポインタ経由で呼び出す時のアセンブリコードはいっしょだという事に解説の後半では主眼を置いている感じがする。x86では、

    mov ecx, [this]
    call [pfunc]

なのだそうな。(Cで似非オブジェクト指向的に組む時のように関数の第一引数がthis pointerを前提にしたmethodの実行コードがコンパイラによって生成されるんだろうか。)

 使ったことは無いけれど、boost::functionが次期標準C++C++0x?)に採用されたようなので今後広まってくらしい。ただDon Clugstonは最適化の観点からそれじゃない方法を望んだようだ。(それが標準C++から逸脱していたとしても。)

 自分が使ってみた感じではDon Clugstonのfastdelegateはまぁ普通に使いやすい。Client Codeが書きやすいし、自分の環境で問題なく使えるので複雑な実装は別に気にしない。利用する環境が限定されてもちゃんと使えて効率が良いっていう事なら特に実装が標準から外れていようが問題は無いと思う。

 Sergey Ryazanovが書いた記事では、実際にfastdelegateが速いのかどうかは実験を経なければいけないとしていて(標準的なboost::functionは動的にメモリを確保しているので遅いのはともかくとして)、ベンチマークコードを用意している。実装はなんだか自作自演をtemplateで生成してる感じ。ただこのアプローチだとpublicなmethodでないと駄目なような気もする。Sergey Ryazanovが出した結論では、標準から外れるのは良く無いし、ハックしたらコンパイラの最適化がうまく効かない事がある、という事だった。あとなんかevent機構用のlibraryなんかも出してた。う〜ん、車輪の再発明だ。既に普及しててノウハウが溜まっているものを使いたいのでパス…。でも時間があったら覗いてみよう。

 とりあえず標準に従う事が第一なら、boost::function。速度を求めたいのならx86限定かもしれないけどfastdelegate。速度が欲しくてそれ以外の環境でも動く標準に則ったのが良いのなら、Sergey Ryazanovのdelegateが良いのかもしれない。