2009/12/22

C#って遅いのか?

C#って遅いのかどうか?といういろいろ荒れがちなセンシティブな話。
でも結構高速化するときに結局どうすりゃいいのかわからなくて困るので
他力本願で収集した内容を分かる範囲でまとめてみる。

1) C#ってVMで中間言語を解釈しながら動いてるわけじゃない

ときどき間違って説明されていることがありますが、
C#って昔のVBのインタプリタとかJAVAのVMとは違って
中間言語を逐次実行してるわけではない。

VB.netの話だけど以下がわかりやすい。C#も同じ。
http://www.atmarkit.co.jp/fdotnet/vbcheer/vbcheer08/vbcheer08.html

だから数値計算とかでベンチマークすると実はかなり速いそうだ。
http://densanshokunin.at.webry.info/200701/article_2.html

でも実際に使っているとなにかとストレスを感じることもあるのは周知の通り。

2) コンパイルの時期に関して
より正確にはここに。
http://msdn.microsoft.com/ja-jp/library/ht8ecch6(VS.80).aspx

> すべての MSIL をネイディブ コードに変換するために時間とメモリを費やすのではなく、
> 実行時に必要になった MSIL を変換し、その結果生成されたネイティブ コードを保存して、
> 以降の呼び出しで利用できるようにしておきます。
> 型が読み込まれると、ローダーはスタブを作成し、その型の各メソッドに結び付けます。
> それ以降は、この JIT コンパイル済みのメソッドを呼び出すと生成済みの
> ネイティブ コードが直接実行され、JIT コンパイルとコードの実行に必要な時間を節約できます。

つまり、フォームを開くのにしてもメソッドを実行するのにしても
「初回だけ」遅い可能性があることになります。
故意に前もって特定のコンパイル実行しておくのも難しいようなので
このへんは気をつけておく必要あり。
最終的にはngen.exeを使った一括先行コンパイルか。試したことないですが。

3)ガベージコレクタの動作に関するオーバーヘッドは読みづらいので注意する必要がある。

ガベージコレクタの動作については以下が詳しい。
http://www.atmarkit.co.jp/fdotnet/directxworld/directxworld06/directxworld06_01.html

でも、結局プロのプログラマでない自分としてはいろいろ調べるのは面倒で、
なるべくobjectのinstanceをpublic宣言して
いろんなところで使いまわす、という腰の引けたコーディングをやりがち。
ホントはもっといいやり方があるはず。

4) System.Windows.Formsって重くないでしょうか。

http://d.hatena.ne.jp/NyaRuRu/20060203#p2
> トップレベルウィンドウとメニューやツールチップなどの一部の特殊ウィンドウのみを
> Win32ウィンドウとし,後はクライアント領域に完全自前描画になったことで,
> やっとInternet ExplorerやFirefox と同じ土俵に上がることができました.
> 要はこれまで WinForms が重かったのはアルゴリズム的問題があったと
> いうことなわけですが,今まで単に「.NET だから重い」と思っていた人は
> もう一度評価し直すべきときがいよいよ来たかと思います.

ちゃんとした検証はできてないですが、
どうもやっぱりFormsの標準コントロールが.net以前と比べて妙に重い気がします。
コントロールをフォーム上に大量配置しただけで露骨に重くなる感じが。

困ったときはすぐダブルバッファリング+自前描画
http://www.atmarkit.co.jp/fdotnet/dotnettips/197doublebuf/doublebuf.html
をやって無理矢理解決してるので、根本的にはどうしたらいいのかさっぱりわからないです。


5) 意外と遅い処理がいろいろあるよう。

C#では意外と遅い特定の処理というのがいろいろあるようで、
そこを気にしないといけないようです。

これについてはまた別途。

0 件のコメント: