アプリケーションのギアを上げよう
― Visual Studio 2010でアプリケーションのパフォーマンス・チューニング ―

第3回 WPFアプリケーション・チューニング

亀川 和史
2011/08/26
2011/08/29 更新
Page1 Page2 Page3

描画性能の測定手順

 「描画性能に関して、どのくらいの差が出るのか」を、標準のTreeViewコントロールで調べてみよう。

 TreeViewコントロールでは、大量の項目が含まれている場合に読み込み時間がかかる場合がある。また、マウス・ホイールやスクロールバーでのスクロールで、UI(ユーザー・インターフェイス)の反応が遅れることがある。

 なお、これらの性能問題はそれぞれ、VirtualizingStackPanel.IsVirtualizing添付プロパティに「true」を設定し、さらにVirtualizingStackPanel.VirtualizationMode添付プロパティに「Recycling」を設定すれば改善する可能性がある(=UIの仮想化を行う設定。詳しくは「MSDN:方法 : TreeView のパフォーマンスを改善する」を参照してほしい)。

 サンプルとして、以下のようなプログラムで30の子項目に、さらに30ずつの孫項目を追加するようなコードを用意する。

TreeViewコントロールに「30の子項目」×「30の孫項目」を追加するサンプル・コード(C#)

 TreeViewコントロールを定義するXAMLコードは下記のとおりだ。

TreeViewコントロールを定義するXAMLコード

 上記のコードを実行すると、以下のようなTreeViewコントロールが描画される。

「30の子項目」×「30の孫項目」を描画するTreeViewコントロールの実行例

 実行中のTreeViewコントロールの描画性能を、Visual Profilerで計測してみよう。以下の画面は、その性能測定の例である。

「30の子項目」×「30の孫項目」を描画するTreeViewコントロールの実行例

 上の画面で赤い線で囲んだ部分でTreeViewコントロールを選択している。[Application CPU Usage]の色と[Element Exclusive CPU Usage]の項目を見ても分かるように、「Layout」の計算で2%程度のCPUを消費している。

TreeViewコントロールにおける「UIの仮想化」

 次に、VirtualizingStackPanelの添付プロパティであるVirtualizationModeとIsVirtualizingを、以下のように変更して、「UIの仮想化」を行う(前述のとおり、この設定により、TreeViewコントロールの性能問題を改善できる)。

TreeViewコントロールの性能問題を改善できる「UIの仮想化」のためのプロパティ設定(XAML)

 そして次の画面のように、再度、プロセスを起動して、描画性能を計測する。

「UIの仮想化」を設定したTreeViewコントロールの性能を、Visual Profilerにより再計測しているところ

 このように「Layout」の再計算で(先ほどの例よりも)負荷がかかっていない状態になったことが分かる。UIの仮想化は、表示領域が少ないにもかかわらず、大量のデータを追加するような場合、表示されていない領域まで計算する必要がないことを明示的に指定する。今回はTreeViewコントロールで例示したが、基本的に表示領域とデータ表示が一致しないようなコントロールでは、UIの仮想化が行われていれば描画性能が向上する。

DataGridコントロールにおける「UIの仮想化」

 日本ではテーブルが好まれることもあり、DataGridコントロールを使おうとすることも多いだろう。.NET Framework 4の標準の(WPFの)DataGridコントロールには、VirtualizingStackPanelの添付プロパティであるVirtualizationModeとIsVirtualizingのほかに、テーブルの列と行に対する仮想化を有効化するためのプロパティであるEnableColumnVirtualizationとEnableRowVirtualizationがある。これらのプロパティを以下のように変更して、再度プロセスを起動して計測する。

DataGridコントロールの性能問題を改善できる「UIの仮想化」のためのプロパティ設定(XAML)
EnableColumnVirtualization属性とEnableRowVirtualization属性を追加した。

 このDataGridコントロールに対して、(64bit版Windowsの)「System32」フォルダ内の全ファイルの情報を(各ファイルにおける、ファイル名、ファイル・サイズ、更新日、作成日などの値を1行分のデータとして)格納しよう。そのコードは次のようになる。

DataGridコントロールに「System32」フォルダ内の全ファイルの情報を追加するサンプル・コード(C#)

 上記のプログラムを実行して、Visual ProfilerによりDataGridコントロールの性能を再計測しているのが、次の画面だ。

「UI仮想化あり」でDataGridコントロールの性能を、Visual Profilerにより再計測しているところ
DataGridコントロールは、WPFアプリケーション全体の「0.38%」の処理時間を占めている。

 上の画面は「UI仮想化あり」で性能を計測した。UIの仮想化の効果を確かめるために、「UI仮想化なし」の場合の性能も計測して両者を比較してみよう。次の画面は、その「UI仮想化なし」の場合の計測結果である。

「UI仮想化なし」でDataGridコントロールの性能を、Visual Profilerにより再計測しているところ
DataGridコントロールは、WPFアプリケーション全体の「0.72%」の処理時間をしめており、前掲の「仮想化あり」と比べてほぼ倍の時間がかかっている。

 DataGridコントロールにおいても「UIの仮想化」を行うことで、性能に改善が見られる。しかしながら、筆者が試した範囲では、速くなるときは今回の例のように半分程度の負荷になるが、遅くなるときはUI仮想化を行っていないときとほとんど変わらない速度になることもあった。上に示した画面ではほとんど速度差がないように見えるが、今回のような描画性能の測定を行うときは複数回採取して確認してほしい。

 また、DataGridコントロールはすべてのデータをメモリに格納するため、例えば標準のDataGridコントロールで(Excelのように)大きなスプレッド・シートを作ろうとすると、巨大なメモリを使用することになる。この問題の解決策としては、データのページングを行い、最初から数十件程度のデータしか取得しないといった方法や、「データ仮想化」(=必要な領域のデータのみ必要なタイミングでメモリに読み込む)といった処理が必要になる。

 DataGridコントロールは便利だが、万能ではない。あらかじめ「大きい」と分かっているデータを表示する場合は注意してほしい。

 次のページからは、Perforatorを紹介する。


 INDEX
  アプリケーションのギアを上げよう ― Visual Studio 2010でアプリケーションのパフォーマンス・チューニング
  第3回 WPFアプリケーション・チューニング
    1.WPF Performance Suiteで描画性能測定
  2.描画性能の測定手順/TreeView&DataGridコントロールにおける「UIの仮想化」
    3.WPF Performance SuiteでGPU描画性能測定/Silverlightのパフォーマンス

インデックス・ページヘ 「アプリケーションのギアを上げよう」

更新履歴
【2011/08/29】

 「●DataGridコントロールにおける「UIの仮想化」」において以下のような誤りがありました。お詫びして訂正させていただきます。

では、DataGridコントロールに対して同様にVirtualizingStackPanelの添付プロパティであるVirtualizationModeとIsVirtualizingの値を以下のように変更して、再度プロセスを起動して計測するとどうなるだろうか?
.NET Framework 4の標準の(WPFの)DataGridコントロールにもVirtualizingStackPanelの添付プロパティであるVirtualizationModeとIsVirtualizingがあるが、そのほかに、テーブルの列と行に対する仮想化を有効化するためのプロパティであるEnableColumnVirtualizationとEnableRowVirtualizationがある。これらのプロパティを以下のように変更して、再度プロセスを起動して計測する。

このように、DataGridコントロールにおいても「UIの仮想化」を行うことで、その性能に改善が見られる。しかしながら、これでも時間がかかっている。.NET Framework 4標準の(WPFの)DataGridコントロールでは、UI仮想化は行方向のみに対して行われており、列方向には行われないからだ。
DataGridコントロールにおいても「UIの仮想化」を行うことで、性能に改善が見られる。しかしながら、筆者が試した範囲では、速くなるときは今回の例のように半分程度の負荷になるが、遅くなるときはUI仮想化を行っていないときとほとんど変わらない速度になることもあった。上に示した画面ではほとんど速度差がないように見えるが、今回のような描画性能の測定を行うときは複数回採取して確認してほしい。




Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

業務アプリInsider 記事ランキング

本日 月間
ソリューションFLASH