DataGridViewとTextRenderer

描画処理を最小限に抑えても、短縮できたのは高々100msという結果になった。残念ながらこの差は自前で描画する理由にはならないだろう。(遅さの)原因はもっと根本的な部分にありそうだ。

描画されるセルの数を増やす意味で、サンプルアプリケーションの起動時のFormのWindowDtateをMaximizeとしてみた。

    • DataGridViewTextBoxCellを使用した場合
DGV Paint( {X=0,Y=0,Width=1600,Height=1154} ) time = 1203 msec.
    • ExtDGVTextBoxCellを使用した場合
DGV Paint( {X=0,Y=0,Width=1600,Height=1154} ) time =  703 msec.

うーん、それでも500ms以内の差か。1秒以上の差がつけば考えたのだが。※1
ちなみにExtDGVTextBoxCellのテキストの描画には、Graphicsクラスのメソッドではなく、TextRendererクラスを使用しているが、実はこのクラス、.NET Framework2.0で追加されたWin32のGDIに相当すると言われているテキストレンダラである。

Visual Studio 2005の、それもβからのユーザは、自動的に生成されるアプリケーションのエントリポイントで、何時の間に以下の行が追加されるようになったのに気がついただろうか。

Application.SetCompatibleTextRenderingDefault(false);

このメソッドはVisual Studio 2005のヘルプでは解説が無いので、全く以って意味不明だが、一般的なコントロール(Button, Label etc.)で実装されているUseCompatibleTextRenderingプロパティの規定値をfalseに設定すること、つまりGDI相当のテキスト描画を使う設定することだろう、ということは調べていると想像がつく。(言っておくが、ソースコードは無いのであくまで「想像」だ)

  • ButtonBase.UseCompatibleTextRendering プロパティ

互換性のあるテキスト レンダリング エンジン (GDI+) またはそれ以外のテキスト レンダリング エンジン (GDI) のどちらを使用するかを決定する値を取得または設定します。

? ちょっと待って欲しい。WindowsXP以降は2DレンダラにはGDI+を、と言っていたはずだが解説からするに、.NET2.0ではGDIをデフォルトの2Dレンダラとしているということになる。何故今更GDIに回帰したのだろう。

今回、DataGridViewのように描画性能の要求が厳しいコントロールをいろいろと弄っていて解ったがGDI相当のAPIは、恐らく必然だったのだろう。といっても、今回のサンプル程度の単純な描画の場合、GDIもGDI+も性能は変わらない(私の環境だけかもしれないが、むしろGDI+の方が少し性能が良かったりする)のだ。

    • GDI+ (Graphics.DrawStringメソッド)を使用した場合
DGV Paint( {X=0,Y=0,Width=1600,Height=1154} ) time =  593 msec.
    • GDI (TextRenderer.DrawTextメソッド)を使用した場合
DGV Paint( {X=0,Y=0,Width=1600,Height=1154} ) time =  703 msec.

結局どちらを使っても、DataGridViewのセルの描画は劇的には改善はされないようだが。

※1 これらの計測値は.NET Frameworkの性能を示す絶対値ではなく、私個人の環境で、描画命令による処理時間の違いを相対的に見るだけのものであり、それ以上の意味は無いことをお断りしておく。