チュートリアル: パフォーマンスの問題を特定する

このチュートリアルでは、アプリケーションのプロファイルを行ってパフォーマンス上の問題を特定する方法を示します。

このチュートリアルでは、マネージ アプリケーションのプロファイリングを行う方法と、サンプリングおよびインストルメンテーションを使用してアプリケーションのパフォーマンス上の問題を特定する方法について、順をおって説明します。

このチュートリアルでは、次の手順を行います。

  • サンプリング方式を使用してアプリケーションのプロファイリングを行います。

  • サンプリングしたプロファイリング結果を分析して、パフォーマンス上の問題を特定および修正します。

  • インストルメンテーション方式を使用してアプリケーションのプロファイリングを行います。

  • インストルメントしたプロファイリング結果を分析して、パフォーマンス上の問題を特定および修正します。

必須コンポーネント

  • C# についての中級レベルの知識。

  • PeopleTrax サンプルのコピー。

    プロファイリングによって得られた情報を操作するには、デバッグ シンボル情報を使用できるようにしておくことをお勧めします。

サンプリング方式を使用したプロファイリング

サンプリングとは 1 つのプロファイリング方式で、対象のプロセスを定期的にポーリングしてアクティブな関数を識別します。 結果のデータからは、プロセスがサンプリングされたときに対象の関数が呼び出し履歴の一番上に配置されていた回数がわかります。

サンプリング方式を使用してアプリケーションのプロファイリングを行うには

  1. 管理者特権で Visual Studio を開きます。 管理者として実行する場合は、プロファイリングが必要です。

  2. PeopleTrax ソリューションを開きます。

    これで、PeopleTrax ソリューションがソリューション エクスプローラーに読み込まれます。

  3. プロジェクトの構成設定を [Release] に設定します。

    アプリケーションにおけるパフォーマンス上の問題を検出する場合は、リリース ビルドを使用する必要があります。 デバッグ ビルドを使用すると、パフォーマンスに悪影響を及ぼす可能性のある追加情報がコンパイルされ、パフォーマンスの問題が正しく示されないことがあるため、プロファイリングにはリリース ビルドを使用してください。

  4. [分析] メニューで、[パフォーマンス プロファイラー][パフォーマンス ウィザード][開始] の順に選択します。

    パフォーマンス ウィザードが表示されます。

  5. [CPU サンプリング (推奨)] が選択されていることを確認して、[次へ] をクリックします。

  6. [プロファイル対象のアプリケーションを選択してください] で [PeopleTrax] を選択して、[次へ] をクリックします。

    Visual Studio によってプロジェクトがビルドされ、アプリケーションのプロファイリングが開始されます。 PeopleTrax アプリケーション ウィンドウが表示されます。

  7. [Get People] をクリックします。

  8. [ExportData] をクリックします。

    メモ帳が開かれ、PeopleTrax からエクスポートされたデータを含む新しいファイルが表示されます。

  9. メモ帳を閉じ、PeopleTrax アプリケーションを閉じます。

    プロファイラーによってプロファイル データ (*.vsp) ファイルが生成され、[パフォーマンス エクスプローラー] ウィンドウの [レポート] セクションにファイル名の一覧が表示されます。さらに、Visual Studio メイン ウィンドウのデータ ファイルの [概要] ビューが自動的に読み込まれます。

サンプリングされたプロファイリング結果を分析するには

  1. [概要] ビューには、プロファイリング実行中における CPU 使用率のタイムライン、最もアクティブなアプリケーションのコール ツリーの分岐を表す [ホット パス] の一覧、関数本体でのコードの実行中に最も頻繁にサンプリングされた関数を表示する [最も頻繁に個別の作業を実行している関数] の一覧が表示されます。

    [ホット パス] の一覧を確認し、PeopleNS.People.GetNames メソッドは一覧の最後の部分に表示されている PeopleTrax 関数であることを確認します。 ここでは、この関数を調べてみることにします。 関数名をクリックすると、GetNames の詳細情報が [関数の詳細] ビューに表示されます。

  2. [関数の詳細] ビューには 2 つのウィンドウがあります。 [コスト配分] ウィンドウには、対象の関数によって実行された処理、対象の関数から呼び出された関数によって実行された処理、対象の関数を呼び出した関数によるサンプリング対象インスタンス数への影響がグラフィック表示されます。 関数名をクリックすると、ビュー内で関数のフォーカスを移動できます。 たとえば PeopleNS.People.GetPeople をクリックすると、GetPeople 関数が選択されます。

    [関数コード ビュー] ウィンドウには使用できる関数のソース コードが表示され、選択された関数内で最も負荷のかかるコード行が強調表示されます。 GetNames を選択すると、この関数はアプリケーション リソースから文字列を読み込み、StringReader を使用して文字列の各行を ArrayList に追加していることがわかります。 この関数を明示的に最適化する方法はありません。

  3. GetNames の呼び出し元は PeopleNS.People.GetPeople だけであるため、[コスト配分] ウィンドウの GetPeople をクリックすると、このメソッドのコードが表示されます。 このメソッドは、GetNames によって取得されたユーザー名と会社名を使用して、PersonInformationNS.PersonInformation オブジェクトの ArrayList を返します。 ただし、PersonInformation オブジェクトが作成されるたびに、GetNames が 2 回呼び出されます。 メソッドの開始時に 1 回だけリストを作成し、PersonInformation の作成ループの実行中にこのリストのインデックスを作成することにより、この関数を簡単に最適化できます。

  4. サンプルのアプリケーション コードには、GetPeople の別バージョンが記述されています。このサンプル コードの場合、条件付きコンパイル シンボルをビルド プロパティに追加することにより、最適化された関数を呼び出すことができます。 この場合、[ソリューション エクスプローラー] ウィンドウで People プロジェクトを右クリックして、[プロパティ] をクリックします。 次に、プロパティ ページ メニューの [ビルド] をクリックし、[条件付きコンパイル シンボル] ボックスに「OPTIMIZED_GETPEOPLE」と入力します。 この状態でビルドを実行すると、最適化されたバージョンの GetPeople によって元のメソッドが置き換えられます。

  5. パフォーマンス セッションを再実行します。 パフォーマンス エクスプローラーのツール バーの [プロファイルを使用して起動] をクリックします。 次に、[Get People] をクリックして [データのエクスポート] をクリックします。 [メモ帳] ウィンドウが表示されたらこのウィンドウを閉じ、次に PeopleTrax アプリケーションを終了します。

    この操作により、新しいプロファイル データ ファイルが生成され、新しいデータ用の [概要] ビューが Visual Studio のメイン ウィンドウに表示されます。

  6. 2 つのプロファイリング実行を比較するには、2 つのデータ ファイルをパフォーマンス エクスプローラーで選択して右クリックし、[パフォーマンス レポートの比較] をクリックします。 [比較レポート] ウィンドウが Visual Studio のメイン ウィンドウに表示されます。 [差分] 列には、[初期値][比較対象値] を基にして、関数のパフォーマンス値における差異が表示されます。 比較対象の値は、[列] ドロップダウン リストから選択できます。 ここでは、[サンプル % (子を含む)] を選択します。

    GetPeople メソッドと GetNames メソッドにより、パフォーマンスが大幅に改善されることを確認してください。

インストルメンテーション方式を使用したプロファイリング

インストルメンテーションは、プロファイリング方法の 1 つです。この方法の場合、特別にビルドされたプロファイリング済みバイナリのバージョンに対して、プローブ関数がプロファイラーによって挿入されます。 挿入されたプローブ関数により、関数内のすべての呼び出しサイトにおいて、インストルメント化されたモジュール内の関数の開始時と終了時のタイミング情報が収集されます。 インストルメンテーション プロセスは、ディスクへの書き込みやネットワーク上での通信など、入出力操作に関する問題を調査する場合に便利です。 インストルメンテーション方式の場合、サンプリング方式よりもさらに詳細な情報を取得できますが、プロセス実行時の負荷が高くなり、オーバーヘッドの量も大きくなります。 インストルメントされたバイナリはデバッグまたはリリース バイナリよりも大きく、配置向けではありません。

ここからは、インストルメンテーション方式を使用して、上でプロファイリングを行った PeopleTrax アプリケーションのコードをさらに最適化できないかどうかを確認します。 具体的には、[概要] ビューのタイムラインのフィルターを使用して、プロファイリング済みアプリケーション (メモ帳ファイルにユーザーのリストを書き込むアプリケーション) におけるデータ エクスポートのシナリオについて確認します。

インストルメンテーション方式を使用して既存のアプリケーションのプロファイリングを行うには

  1. 必要に応じて、PeopleTrax アプリケーションを Visual Studio で開きます。

    管理者として実行していること、およびソリューションのビルド構成が [解放] に設定されていることを確認します。

  2. パフォーマンス エクスプローラーで、[インストルメンテーション] を右クリックします。

  3. パフォーマンス エクスプローラーのツール バーの [プロファイルを使用して起動] をクリックします。

    プロファイラーによってプロジェクトがビルドされ、アプリケーションのプロファイリングが開始されます。 PeopleTrax アプリケーション ウィンドウが表示されます。

  4. [Get People] をクリックします。

    PeopleTrax データ グリッドにデータが設定されます。

  5. 10 秒ほど待機してから、[データのエクスポート] をクリックします。

    メモ帳が開かれ、PeopleTrax の人名リストを含む新しいファイルが表示されます。 待機することにより、フィルター処理用のデータ エクスポート手順をさらに簡単に識別できます。

  6. メモ帳を閉じ、PeopleTrax アプリケーションを閉じます。

    Visual Studio によって、パフォーマンス セッション レポート (*.vsp) が生成されます。

インストルメントされたプロファイリング結果を分析するには

  1. レポートの [概要] ビューのタイムライン グラフには、プロファイリング実行中のプログラムによる CPU 使用率が表示されます。 上で実行したデータのエクスポート操作は、このグラフの右側に急激な上向きの折れ線 (または水平線) として表示されます。 パフォーマンス セッションをフィルター処理すると、エクスポート操作で収集されたデータだけを表示して分析できます。 その場合、エクスポート操作が開始された位置の左側をグラフ上でクリックします。 次に、その位置の右側をもう一度クリックします。 さらに、タイムラインの右側に表示されているリンクの一覧内の [選択項目でフィルター] をクリックします。

    PeopleTrax.Form1.ExportData メソッドから呼び出された Concat メソッドが大量の時間を消費していることが、[ホット パス] ツリーにパーセンテージで表示されます。 System.String.Concat[個別作業が一番多い関数] の一覧の先頭に表示されているため、この関数による処理時間の削減も最適化につながります。

  2. いずれかの概要テーブルで [System.String.Concat] をダブルクリックし、[関数の詳細] ビューで追加情報を表示します。

  3. ビューを確認すると、Concat を呼び出しているメソッドは PeopleTrax.Form1.ExportData だけだということがわかります。 [呼び出し元の関数] の一覧で [PeopleTrax.Form1.ExportData] をクリックし、[関数の詳細] ビューのターゲットとしてこのメソッドを選択します。

  4. [関数コード ビュー] ウィンドウのメソッドを確認します。 System.String.Concat へのリテラル呼び出しがないことがわかります。 その代わりに、+= オペランドがいくつか使用されています。これらのオペランドは、コンパイラによって System.String.Concat への呼び出しに置き換えられます。 .NET Framework で文字列に変更を加えると、新しい文字列が割り当てられます。 .NET Framework には、文字列の連結用に最適化された StringBuilder クラスが用意されています。

  5. この問題領域を最適化されたコードに置き換えるために、PeopleTrax プロジェクトに OPTIMIZED_EXPORTDATA を条件付きコンパイル シンボルとして追加します。

  6. ソリューション エクスプローラーで、PeopleTrax プロジェクトを右クリックし、[プロパティ] をクリックします。

    PeopleTrax プロジェクトのプロパティ フォームが表示されます。

  7. [ビルド] タブをクリックします。

  8. [条件付きコンパイル シンボル] ボックスに、「OPTIMIZED_EXPORTDATA」と入力します。

  9. プロジェクトのプロパティ フォームを閉じ、確認メッセージが表示されたら [すべてを保存] をクリックします。

    アプリケーションを再度実行すると、パフォーマンスが大幅に改善されたことがわかります。 ユーザーが知覚できる程度にパフォーマンスが改善された場合でも、プロファイリング セッションを再び実行することをお勧めします。 ある問題によって他の問題の存在が表面化しない場合があるため、問題を解決したら必ずデータをレビューする必要があります。

関連項目

概要
はじめに
/Z7、/Zi、/ZI (デバッグ情報の形式)