2009/12/23

C#のコードを高速化するための方法

以前のものの続き。
C#ならではのコーディングの際に注意するところまとめ。

○クラスと構造体の選択方法

オブジェクトのインスタンス生成はかなり重たい処理であるよう。

で、C#にはオブジェクトをヒープ内でなく、
スタックに積むための「構造体」という仕組みがあるのですが、
http://www.atmarkit.co.jp/fdotnet/special/java2cs/java2cs_01.html

構造体は値型であるためそのサイズが大きい場合にはかえってその受け渡し時の
コピーに負荷がかかってしまうよう。
http://www.atmarkit.co.jp/fdotnet/directxworld/directxworld06/directxworld06_04.html

構造体を使うかクラスを使うかの境界線はそのサイズで決まるようなの
ですが、その境界は意外と低くて16バイト以上のものはクラスを使ったほうがいいよう。

クラスと構造体の選択
http://msdn.microsoft.com/ja-jp/library/ms229017.aspx
実検証結果
http://mag.autumn.org/Content.modf?id=20061014194823

実際には構造体を使ったほうが得をする場合は
結構限られている感じをうけます。


○キャストはすごく重そうだ

型キャストはちょっと意外なぐらい重い。
http://www.atmarkit.co.jp/fdotnet/dotnettips/005castandas/castandas.html

上記のリンクにもあるように、参照型のキャストにはasを使ったほうが速い。
でも、asを使ってもそれなりに重い処理ではある。

Collectionはキャスト必須になってしまうので、
なるべく代わりにGenericを使ったほうが良い。

http://www.atmarkit.co.jp/fdotnet/csharp20/csharp20_02/csharp20_02_01.html
http://life-hack.jp/blog/charly/95

イベントハンドラでsenderを繰り返し使うと重くなるので、
senderは早めにas演算子でなんらかの型に変換しちゃったほうが良いみたい。


○多次元配列は比較的重い

多次元配列(x[i,j])よりジャグ配列(x[i][j])使ったほうが速いそうです。
http://d.hatena.ne.jp/EmK/20081130/1228025602
重い数値計算とかやる場合に影響するかも。

C++の多次元配列は実質的には単なるポインタ経由のアクセスなんで
べらぼうに速いですね。やっぱり。


○文字列の連結処理

頻繁な文字列の連結はメモリ中のコピーを繰り返すので遅い
http://www.atmarkit.co.jp/fdotnet/dotnettips/029strcat/strcat.html
ベンチマーク結果
http://sonic64.com/2005-11-30.html

stringbuilderを使うと高速化できる。
そこまで重い処理ではないので、ホントに大量の連結
を繰り返す場合にだけ対策が必要。


○画像処理

BitmapのGetPixel, SetPixelは画像処理に使うにはちょっと重すぎる。
http://www.atmarkit.co.jp/fdotnet/csharp_abc/csharp_abc_021/csharp_abc05.html

本気で画像処理するときには、unsafeになるけど
ポインタを使うしかないと思う。


○.net Frameworkの起動が遅い

Windows XPだと初回のアプリ起動時に.net Framework自体を起動しに行く。
http://ameblo.jp/norixp/entry-10013581738.html

対策するとしたら、
上のリンクのように別アプリでスプラッシュウィンドウを出す、とか、
スタートアップに空の.netアプリを入れとくか。

Vista以降だと最初から起動してるから
これがなくて速いんでしょうか?

0 件のコメント: