hIDDEN bLOG » .NETでの、画像などの生データへのアクセス速度について

2007/10/12 金曜日

.NETでの、画像などの生データへのアクセス速度について

このエントリをはてなブックマークに追加
Filed under: .NET — @ 9:35:13

■追記■
後述のデバッグ時にやたら重くなる件、回避策が見つかったので
こちらにエントリ。 

.NETで画像などのバイナリ生データへアクセスする際、結局のところどうやって記述するのがベストなんだろうかと思って、数パターンのベンチをとってみた。

内容

1280×1024サイズの画像を諧調反転する処理を、以下の4パターンで実行し処理時間を計測。
(VisualStudio2005+C#でプロジェクトを作成)

1.GetPixel / SetPixel
BitmapクラスのGetPixel / SetPixelメソッドを利用して、ピクセルにアクセスする。

2.Marshal
System.Runtime.InteropServices.MarshalクラスのReadByte / WriteByteメソッドを利用して、ピクセルにアクセスする。

3.Array
Bitmap.LockBitsによりロックしたバッファをbyte配列にコピーし、配列操作によりピクセルにアクセスする。

4.unsafe
unsafeキーワードによりポインタを直接操作し、ピクセルにアクセスする。

結果

EXE単体(Debug)

GetPixel / SetPixel 2,828ms
Marshal 438ms
Array 266ms
unsafe 265ms

EXE単体(Release)

GetPixel / SetPixel 2,813ms
Marshal 375ms
Array 234ms
unsafe 266ms

デバッグ実行(Debug)

GetPixel / SetPixel 98,312ms
Marshal 197,375ms
Array 12,141ms
unsafe 12,125ms

デバッグ実行(Release)

GetPixel / SetPixel 100,234ms
Marshal 198,516ms
Array 12,688ms
unsafe 12,281ms

総評

まず、デバッグ実行では、すべてのパターンで、かなりのパフォーマンスの悪化がみられた。
おそらくデバッガでのデータアクセス監視などによるロスだと思うが、開発に支障をきたすほどの落差なので、対策・調査が必要かなと

EXE単体で実行の場合、処理時間はだいたい以下のような関係かと。
「GetPixel / SetPixel」>>>>>「Marshal」>「Array」≒「unsafe」

「GetPixel / SetPixel」の重さは群を抜いているので、
サンプルプログラムなどの限定的な用途以外にはあまり向かないかと。

可読性は↓
「Array」≒「unsafe」>「Marshal」
メモリ使用量は↓
「Array」>「Marshal」≒「unsafe」
といったところ。

総合すると、「Marshal」の場合は若干可読性に難があり、「Array」の場合は画像とは別に配列のメモリ使用量が増加するため、総合的には「unsafe」がベストではないかという結論に至った。

しかし例えば、マウスの指す1点の色を取得するなどだけなら、GetPixelで十分だろう。
実際は、適宜トレードオフにより取捨選択になるかと。

3件のコメント »

コメントはまだありません。

この投稿へのコメントの RSS フィード。 TrackBack URL

コメントする

HTML convert time: 0.742 sec. Powered by WordPress