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

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

亀川 和史
2011/08/26
Page1 Page2 Page3

 「WPF製プログラムの画面描画が遅い」という現象に悩まされていないだろうか?

 Visual Studio標準ではないが、Windows SDKにはWPFプログラムの描画性能を調査するツールがいくつか用意されている。本稿では、これらの役に立つツールについて解説する。なお、本稿のサンプル・コードはすべてC#を使用する。

WPFのパフォーマンス

 アプリケーションで「性能が出ない」という場合、いろいろな原因が考えられる。Webサービスからデータを取得して可視化して表示するアプリケーションを考えた場合、以下の3点のいずれかで時間がかかっていると考えられる。

  • データベース・サーバからのデータ取得
  • Webサービス内のロジック処理
  • クライアントサイドでの処理が遅い(WPFであれば「バインディングや画面描画」、Webブラウザであれば「JavaScriptでのDOM操作」など)

 アプリケーションを使用するエンド・ユーザーからは(その原因が何であれ)「アプリケーションが遅い」という同一の報告を受けることになるが、遅い処理が発生している場所によって対処方法は異なるわけだ。そこで本稿では、この中から特に「WPFアプリケーションでの描画性能の調査方法」を解説する。

WPF Performance Suiteで描画性能測定

 Windows SDKには、WPFの描画性能を測定する「WPF Performance Suite」(=「Performance Profiling Tools for WPF」とも呼ばれる)が付属している。これを実際に利用するには、標準で「C:\Program Files\Microsoft Windows Performance Toolkit\WPF Performance Suite」フォルダにインストールされている「WpfPerf.exe」というプログラムを起動する。

 なお、WPF Performance Suiteを使用するには、次の画面のように、Windows SDKのインストール時に[Windows Performance Toolkit]にチェックを入れておく必要がある。

Windows SDKのインストール時に[Windows Performance Toolkit]にチェックを入れておく

 Windows SDKの現時点の最新版は、「Windows SDK for Windows 7 and .NET Framework 4」である。

 Windows SDK for Windows 7 and .NET Framework 4のWPF Performance Suiteをインストールしても、既知の問題によりプロファイルを行えないので、インストール後にパッチの適用が必要になる。以下のブログ(英語)で詳細が述べられているが、特定のタイムゾーンで実行する場合に発生する問題であり、日本のタイムゾーンはこの問題が発生する条件に一致しているため、必ず適用してほしい。

 パッチのインストールは極めて簡単だ。ダウンロードした「WpfPerf_timezone_patch.msp」ファイルを実行して、以下の手順を実施すればよい。

[Next]ボタンを押す
[Repair]ボタンを押す
[Repair]ボタンを押すと、インストールが実行され、パッチが適用される

その後、[スタート]メニューから「Microsoft Windows Performance Toolkit」プログラム・グループにある「WPF Performance Suite」を実行する
WPF Performance Suite Patchのインストール手順

 「WPF Performance Suite」を起動しようとするとUAC(ユーザー・アカウント制御)による特権昇格確認が行われ、最初にツールを追加するためのウィンドウが表示される(次の画面を参照)。

WPF Performance Suite(=Performance Profiling Tools for WPF)の起動
初回起動時には、[Perforator - Analyze rendering behavior]と[Visual Profiler - Profile WPF Services]の両方のチェックボックスにチェックを付ける。
  [Perforator - Analyze rendering behavior]チェックボックス:システム環境におけるグラフィックス機能の描画性能(=レンダリング性能)を解析するツール。
  [Visual Profiler - Profile WPF Services]チェックボックス:WPFアプリケーションの要素ごとの描画性能を解析するツール。

 [Perforator - Analyze rendering behavior](以下、Perforator)と[Visual Profiler - Profile WPF Services](以下、Visual Profiler)の両方のチェックボックスにチェックを付けて[OK]ボタンを押すと、「WPF Performance Suite」(=「Performance Profiling Tools」)が起動する(チェックを付けた項目は、次回以降の起動時に自動的に読み込まれるので、この作業は初回のみでよい)。

 Visual Profilerは、WPFのレイアウト・システムでの各要素の描画性能の測定に役立つ。

 一方のPerforatorは、グラフィックス機能の描画性能の測定に役立つ。

 以下では、それぞれのツールについて詳しく解説する。

Visual Profiler

 Visual Profilerの使い方としては、デバッガと同様に、「実行中のプロセスにアタッチする方法」と「Performance Profiling Toolsから性能測定したいプログラムを呼び出す方法」の2つがある。これらは、(メニューバーの)[Actions]メニューから実行できる(次の画面を参照)。

Visual Profilerの使用開始
Visual Profilerの使い方には、の2つの方法がある。
  実行中のプロセスにアタッチする方法:現在起動しているプログラムから選択する(WPF製のプロセスのみが一覧に表示される)。
  Performance Profiling Toolsから性能測定したいプログラムを呼び出す方法:指定したプログラムを起動する。
  性能測定を中止する。

 メニューバーから[Actions]−[Select Process]メニューを選択すると、以下のダイアログが表示され、任意の実行中WPFアプリケーションを選択できる。

Visual Profilerにおける、任意の実行中WPFアプリケーションの選択
メニューバーから[Actions]−[Select Process]メニューを選択して、[Select Process]ダイアログが表示されたところ。
  [Hide window while dragging]チェックボックスをチェックして、左側の赤枠で囲まれているターゲット・マークをドラッグすればPerformance Profiling Toolsが自動的に非表示になり、任意のウィンドウを選択できるようになる。広くないディスプレイでウィンドウを選択する際に便利だ。
  現在実行中のWPFアプリケーションの一覧を表示している。タスク・マネージャと同様、プロセス名の末尾に「*32」と付いているのは64bit OSにおける32bitアプリケーションのことである。[CLR Version]列で、CLRのバージョンの区別が可能だ。.NET Framework 3.5 SP1までの.NET Frameworkで作られたアプリケーションは「V2」と表示される。

 また、メニューバーから[Actions]−[Launch Process]メニューを選択すると、以下の画面が表示され、ファイル・パスから任意のWPFアプリケーションを指定できる。

Visual Profilerにおける、任意のWPFアプリケーションの指定
メニューバーから[Actions]−[Launch Process]メニューを選択して、[Launch Process]ダイアログが表示されたところ。
  プログラムをフルパスで選択する。[Browse]ボタンを押せば、[ファイルを開く]ダイアログが表示される。
  プログラム起動時に引数が必要な場合は指定する。必要ない場合は指定しなくてもよい。
  プログラムの作業フォルダを指定する。
  実行するCLRのバージョンを指定する。通常は[Auto]で問題ない。
  制限ユーザーで起動させる場合にチェックする。WPF Performance Toolsは昇格した状態で起動している。よって、昇格した状態で起動されると動作に影響があるようなアプリケーションを実行する場合はここにチェックを付ける。

 [Select Process]、[Launch Process]のいずれのメニューを選択しても実行できる機能に変わりはない。以下は、代表的なWPFアプリケーションであるVisual Studio 2010を実際に[Select Process]で選択した場合の性能計測の例である。

Visual Profilerによる性能測定の例
代表的なWPFアプリケーションであるVisual Studio 2010を実際に[Select Process]で選択した場合の、性能計測の例。Visual Profilerは、WPFのレイアウト・システムでの各要素の描画性能の測定に役立つ。上部の[Visual Profiler]タブを選択すると、この画面が表示される。
  CPU使用率グラフを拡大/縮小する。
  WPFの要素を検索する。
  WPFの要素ツリーを表示する。要素ツリーの後ろの数字は、その要素における使用率である。以下に[View]メニューで表示/非表示を切り替える。

メニュー項目 説明
Check all 下の5項目をすべてチェックする
Uncheck all 下の5項目すべてのチェックを外す
# Visual Descendants ビジュアル・ツリーの子孫の数を表示する
Inclusive この要素を含んだツリー配下のCPU使用率(%単位)
Exclusive この要素のみのCPU使用率(%単位)
Inclusive Time このツリー全体のCPU使用時間(ミリ秒単位)
Exclusive Time この要素のみのCPU使用時間(ミリ秒単位)
[View]メニューの項目一覧
  で選択された要素のイメージをプレビューする。の[Live Preview]が有効な状態になっている必要がある。
  で選択された要素の描画を行う際にCPUが使用された時間。例えばウィンドウの再配置などを行う際にこのグラフの描画を見ればよい。Visual Studioの場合、エディタのドッキング・ウィンドウをフロート状態にして、リサイズするとこのグラフに使用率が描画される。
  の選択された要素がどんな動作(描画、サイズ計算、配置)を行っているか、表示する。
  アプリケーションが使用しているCPUの使用率。
  アプリケーション内でどの処理に時間を消費しているかというイベントごとの詳細。イベントについては、下記の「WPFにおける描画関連イベントの一覧」を参照してほしい。
  キャプチャ処理を一時停止/再開する。
  このボタンを押すと、のプレビュー画面を自動的に更新する。もう一度押すと、自動更新を停止する。有効にしておくと、例えば対象のウィンドウをリサイズした場合、のプレビューも自動的に表示が変更される。性能に影響があるため、必要な場合のみに使用する。
  このボタンを押すと、で選択した要素を黄色い枠で囲んで表示する。実際にどのウィンドウを選択しているのか、視覚的に分かりやすくなる。例えば、Visual Studioの[プロパティ]ウィンドウの要素をで選択すると、以下のようにVisual Studioのプロパティウィンドウの枠も黄色で表示される。
  キャプチャした範囲データの拡大・縮小を行う。随時、データが流れているので、一時停止状態にしてから操作を行う必要がある。図の黒い線を左右にドラッグすれば、範囲を左右にずらせる。また、連動して、のグラフ描画も変更される。
  のグラフ描画を変更する。以下の3通りのいずれかを選択する。
 (1)Compare relative weights dynamically:選択されたタイミングにおけるCPU使用率を相対的な使用率で表示する
 (2)Compare absolute values dynamically:タイムスライス中で最大のCPU使用率を基準にして表示する
 (3)Define fixed maximum:横のスライダで基準値を上下させて決定する

 下記の表は、WPFにおける描画関連イベントの一覧である。

イベント名 説明
Dispatcher Invoke ディスパッチ処理に使用した時間
UCE Process Queue CPUがレンダリング用スレッドにデータを送るために使用した時間
RenderMessageHandler(MediaContext) レンダリング・パスの初期化が行われると発生する。
Rendering Thread レンダリング処理が開始されると発生する。
Layout サイズ計算、配置、レンダリング・パスなどが発生したときに記録される
UpdateRealizations テキストおよびビットマップ描画が更新されるタイミングで発生する
Tick(TimeManager) アニメーション間隔が発生したタイミングで、アニメーション描画処理から発生する
AnimatedRenderMessageHandler(MediaContext) アニメーションが有効な場合、プロパティ変更に伴い、アニメーションが更新され、描画が開始されるタイミングで発生する
Render(MediaContext) レンダリング処理中に発生する。OnRenderメソッドが要素から呼び出されたタイミングで発生する
WPFにおける描画関連イベントの一覧

 .NET Framework 3.xまでのWPFプログラムの場合、以下のイベントも記録される。

イベント名 説明
UpdateEffectiveValue(DependencyObject) 依存関係プロパティでプロパティに変更があった場合に発生する
Hit Testing オブジェクトのヒットテスト(マウスでクリックされたとか)が発生した場合に記録される
FormatLineInternal(TextFormatterImp) テキストの書式設定を行う際に発生する
MarkVisibleRealizations(Visual) テキストのビットマップ効果を更新する必要がある際に発生する
.NET Framework 3.xまでの場合に記録されるイベントの一覧

 このような機能を提供するVisual Profilerは、例えばカスタム・コントロールを開発する際に役立つ。1つ1つのカスタム・コントロールは必要な性能要件を満たしているにもかかわらず、WPF画面上に多くのコントロールを配置するとすべてのコントロールが遅くなる場合は、トータルの画面描画時の描画性能を測定する必要がある。特に業務アプリケーションではWPF画面上に多くのコントロールを配置することがよくあるので、そのようなケースでVisual Profilerが役立つだろう。

 続いて、描画性能の測定手順を見ていこう。


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

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


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