ホーム テクノロジー 開発 13 アプリケーションのパフォーマンスの問題をデバッグするためのソフトウェアのプロファイリング

13 アプリケーションのパフォーマンスの問題をデバッグするためのソフトウェアのプロファイリング


アプリケーションの目的は、エンドユーザーに適切なサービスを提供することです。

他の望ましい機能の中でも特に、高速で応答性が高く、使いやすく、信頼性が高くなければなりません。

しかし、最高レベルのパフォーマンスを提供し続ける方法でソフトウェアを保守することは、それほど簡単ではありません。

コードが不要な関数を呼び出し始めたり、コード自体が暴走したり、バグを見つけたり、余分なループに入ったりすると、非効率が生じる可能性があります。アプリケーションが遅くなったり、応答しなくなったり、不安定に動作したりする可能性があります。

これらの問題を解決しないと、アプリケーション全体のパフォーマンスが低下します。

その結果、パフォーマンスの低下や速度の低下により、顧客がイライラしたり、アプリケーションの使用を完全にやめたりする可能性があります。それはあなたの評判を落とすだけでなく、収益と利益の面でも損失をもたらします。したがって、最適なパフォーマンスを達成するには、コードを分析、レビュー、デバッグする必要があります。これを簡単に行う方法は、ソフトウェア プロファイリング ツールを使用してコードを監視およびデバッグし、パフォーマンス関連のボトルネックを排除することです。

この記事では、ソフトウェア プロファイリングとそれがどのように役立つかについて説明します。次に、アプリケーションをデバッグしてパフォーマンスを最適化するための最良のプロファイリング ツールをいくつか紹介します。

ソフトウェアプロファイリングとは何ですか?

ソフトウェア プロファイリングは、プログラムの実行中に収集されたデータを使用してプログラムの動作を調査する動的コード分析です。これは、アプリケーションの速度と応答性を向上させ、メモリとリソースの消費を削減するために最適化する必要があるさまざまなプログラム セクションを決定することを目的としています。

ソフトウェア プロファイラは通常、プログラムに関連するメモリまたは時間の複雑さとともに、関数呼び出しの継続時間と頻度を測定します。メモリ プロファイラーなどの特定のプロファイラーも利用できます。

プロファイリングは通常、プログラムのソース コードをインストルメントすることによって実行されます。プロファイラーは、インストルメント化、イベントベース、統計、シミュレーション手法など、さまざまなプロファイリング手法を使用できます。

ソフトウェアプロファイリングが重要なのはなぜですか?

ソフトウェア プロファイリングは、特定の機能に関連するリソースの使用量と実行時間を判断するために必要です。これにより、プログラムの速度が最適化されると同時に、消費されるリソースが最小限に抑えられます。

さらに、CPU 使用率とコマンド実行時間を追跡し、最適化するために行われます。

したがって、パフォーマンス関連の問題をより迅速にデバッグして効率を高め、より良いエンドユーザー エクスペリエンスを提供するには、適切なソフトウェア プロファイリング ツールを選択することが必要です。多くのプロファイラーには、問題の正確な根本原因を見つけて解決を容易にする詳細なレポート、インタラクティブなグラフと視覚化機能も付属しています。

そこで、ここでは試してみて最も効果があったソフトウェア プロファイラーのリストをいくつか示します。

スパイ、スパイ

py-spy は、Python 用の優れたサンプリング プロファイラーです。これにより、Python ベースのアプリケーションが費やしているすべてのことをこっそり見ることができます。

このために、コードを変更したり、プログラムを完全に再起動したりする必要はありません。 py-spy はオーバーヘッドが低く、実行速度を高めるために Rust で開発されています。プロファイリングされた Python ベースのプログラムが実行されるのと同じプロセスで動作するようには構築されていません。これは、py-spy が本番環境の Python ベースのコードに対して使用するのに非常に安全でセキュアであることを意味します。

このツールを使用すると、プロファイルを記録し、フレーム グラフを生成してインタラクティブな SVG ファイルを作成できます。サンプリング レートの変更、プロファイリング用のネイティブ C 拡張機能、サブプロセス、スレッド ID など、他のオプションも表示できます。 「top」コマンドを使用してプログラム内で発生している関数のライブビューを取得したり、「dump」コマンドを使用してすべての Python スレッドの現在のコールスタックを表示したりできます。

2.3 ~ 2.7 および 3.3 ~ 3.8 など、すべての CPython インタープリター バージョンをサポートします。 py-spy は PyPI または GitHub からインストールできます。

パイロスコープ

Pyrscopeのオープンソースの継続的プロファイリング ソフトウェアを使用すると、アプリケーション内のすべてのパフォーマンスの問題を数分でデバッグできます。

Docker、Linux など、何を使用していても、サーバーを起動してからエージェントを起動することができます。また、Ruby や Go ドキュメントを探している場合でも、Pyrscope がカバーします。 10 秒または 10 か月のソフトウェア プロファイリング データを目的とする場合でも、カスタム設計のストレージ エンジンが高速クエリを実行します。

パフォーマンスに影響を与えないサンプリング プロファイリング テクノロジーを使用しているため、オーバーヘッドやアプリケーションのパフォーマンスを心配する必要はありません。 Pyrscope はプロファイリング データを効率的に保存します。したがって、さまざまなアプリケーションからのさまざまなプロファイリング データを何年にもわたって保存したい場合でも、コスト効率が高くなります。

macOS、Linux、Docker 上で動作し、Python、Go、Ruby で書かれたプログラムをサポートします。

バブルプロフ

Clinic.js のBubbleprofは、Node.js で書かれたソフトウェアをプロファイリングする新鮮でユニークな方法を提供します。これは、専門家から初心者まで、アプリ内で費やした非同期時間を判断するのに役立つ「バブル」UI を使用します。

Node.js プロセスの非同期操作を観察し、グループ化し、遅延を計算し、マッピングすることで、そのプロセスがどのように動作するかを視覚化します。

Bubbleprof は、コード、ノード コア、またはモジュールなどの特定の操作グループ内のバブルのサイズを調べることによって、操作のタイミングを決定します。また、隣接するグループをクラブ化して乱雑さを減らします。

操作があるグループから別のグループに流れるときの遅延を計算するために、Bubbleprof はバブルを接続する矢印の長さを測定します。これに加えて、測定プロセスでも異なる色が使用されます。同時に、内側の色付きの線は、遅延の原因として非同期操作タイプの混合を表しています。

ピンインストゥルメント

Pyinstrumentを使用して Python コードを最適化します。

Python コードが遅い理由を示し、問題の診断に役立つため、驚異的な高速パフォーマンスを実現できます。

Pyinstrument を使用するには、Python スクリプトを作成する必要はありません。コマンドラインを使用して直接 Pyinstrument を呼び出すだけです。スクリプトは通常どおり実行され、ツールはアプリケーションが時間を費やした領域の色付きの概要を生成します。プロセスをさらに簡単にする Python API も付属しています。

Flask や Django でも Web リクエストをプロファイリングするオプションがあり、詳細なドキュメントが維持されています。ここで、Pyinstrument は、プログラムによって行われたすべての関数呼び出しを追跡するのではなく、1 ミリ秒ごとに呼び出しスタックを記録する統計的プロファイリングを提供していることに注意してください。

統計プロファイラーはトレース プロファイラーに比べてオーバーヘッドが少ないため、利点があります。スタック全体を記録するため、高価な関数呼び出しの追跡が簡単になります。これに加えて、Pyinstrument は (デフォルトで) ライブラリ フレームも非表示にするため、パフォーマンスに影響を与えるアプリケーションやモジュールに集中できるようになります。

Pyinstrument は「実測」時間を使用して費やした時間を記録するため、パフォーマンスの問題のデバッグが容易になります。このツールは、ファイルの読み取り、データのダウンロード、データベースとの通信などにかかるプログラムの時間をすべて追跡します。

Xデバッグ

コードのパフォーマンスの問題を改善し、開発体験をもう少し楽しくするために、 Xdebugにはプロファイリングとデバッグのための幅広い機能が付属しています。

これは実際には PHP 拡張機能で、PHP アプリケーションのボトルネックを見つけ、外部視覚化ツールを使用してそのパフォーマンスを分析し、パフォーマンス グラフを生成することができます。

Xdebug は、特定の関数に渡されたパラメーターを含む、アプリケーションがエラーに到達するまでのパスを示す詳細な出力を作成します。これはエラーを追跡するために行われます。開発者が物事を明確に理解できるように、構造化されたビューとともに色分けされた情報が生成されます。

リモート デバッガも付属しており、これを使用して Xdebug を実行中のコード、IDE、またはブラウザに接続して、コードのブレークポイントを確認し、コードを 1 行ずつ実行できます。提供するもう 1 つの機能は、プログラムのコードがどの程度実行されたかを示すコード カバレッジであり、単体テストにも役立ちます。

SPX

Simple Profiling eXtension ( SPX ) は、PHP 用に設計されたプロファイリング拡張機能です。これには、他のプロファイリング拡張機能とは異なる、いくつかのユニークなプロパティがあります。完全に無料で使用でき、インフラストラクチャ内でのみ使用できるため、データ漏洩のリスクはありません。

SPX はシンプルであるため、非常に使いやすくなっています。必要なのは、コマンド ラインまたは環境変数を設定してスクリプトをプロファイリングすることだけです。または、Web ページ上のラジオ ボタンをオンにしてスクリプトをプロファイリングすることもできます。その結果、コードを手動でインストルメントする必要がなくなります。

コマンドライン スクリプトの実行 (Ctrl-C) もサポートしています。これに加えて、このプロセスにより、コマンドライン ランチャーや専用のブラウザ拡張機能を使用する必要もなくなります。 SPX は、さまざまな時間とメモリのメトリクス、オブジェクト、使用中のファイル、I/O などを含む、約 22 のマルチ メトリクスをサポートします。

コンテキストを離れることなくデータを収集できます。その Web UI では、現在使用中のブラウザ セッションのプロファイリングを構成/有効にすることができ、プロファイリングされたすべてのスクリプトの詳細とレポートが一覧表示されます。 Web UI では、特定のレポートを選択してより詳細な分析を行うことができ、Flamegraph、フラット プロファイル、タイムラインなど、数百万単位の関数呼び出しにスケールできる対話型の視覚化機能を備えています。

プレフィックス

Prefix by Stackify は、多くの開発者に愛用されている、インストールが簡単で軽量なコード プロファイラーです。アプリケーションのパフォーマンスのボトルネックを排除して最適化し、ユーザー エクスペリエンスを向上させるのに役立ちます。

Prefix の優れたトレース機能とプロファイリング機能により、隠れた例外や遅い SQL クエリなどをすばやく見つけることができます。これにより、開発者は APM (アプリケーション パフォーマンス モニタリング) の真の力を得ることができます。このため、Prefix はコードのパフォーマンスをその記述どおりに検証し、よりパフォーマンスの高いコードをテストにプッシュできるようにします。

このようにして、運用側から受け取るサポート チケットが減り、開発マネージャーがより早く目標を達成できるようになります。パフォーマンスの低いクエリ、未知のボトルネック、ORM によって生成されたクエリをすべて検出します。

各 SQL 呼び出しパラメーターを追跡し、タイミングをダウンロードし、影響を受けるレコードを表示することもできます。プレフィックスを使用すると、N+1 パターンも簡単に見つけることができます。面倒なログをすべて整理することは忘れてください。それらをまとめて問題を簡単に特定します。

プレフィックスを使用すると、クエリ リクエスト内の疑わしいログのコンテキストを直接見つけて、1 つのログからトレースにジャンプしてデバッグを簡単に行うことができます。プレフィックスは、パフォーマンスの低い依存関係を明らかにします。これは、隠れた例外を見つけたり、レガシー コードやフレームワーク セクションを操作したりするのに役立ちます。これらの依存関係には、Web サービス、サードパーティ サービス、キャッシュ サービスなどが含まれます。

Prefix は Windows と Mac で動作し、.Net、Ruby、Java、PHP、Python、Node.js をサポートします。

不等辺角

Scaleneは、Python ベースのプログラム用の高精度、高性能の GPU、CPU、メモリ プロファイラーです。これには、桁違いに高速に実行したり、より詳細な情報を提供したりするなど、他のプロファイラーに比べていくつかの利点があります。

Scalene は信じられないほど高速で、計測ではなくサンプリングを利用します。 Python のトレース機能にも依存しません。これに加えて、そのオーバーヘッドは通常 10 ~ 20% 未満です。このツールは行レベルでソフトウェア プロファイリングを実行し、プログラムの実行時間に関与するコード行を示します。

これらの詳細は、機能レベルのプロファイリングよりも価値があります。 Scalene は、純粋に Python に費やす時間を、ライブラリを含むネイティブ コードに費やす時間を分離します。ほとんどの Python プログラマーはネイティブ コードのパフォーマンスを最適化しないため、開発者は実際に改善できるコードの最適化に注力できます。

ホットスポットが赤で強調表示されるため、CPU 時間/メモリ割り当てを見つけやすくなり、システム時間を簡単に分離して I/O の問題を見つけることができます。 Scalene は、GPU 時間をレポートし、メモリ使用量をプロファイルし、CPU 使用量を追跡できます。 Scalene は、メモリ リークの可能性を特定し、コピー ボリュームをプロファイルし、CPU の 1% を超えるコード行を消費する削減プロファイルを生成することもできます。

VisualVM

Java 用オールインワン トラブルシューティング ツールVisualVM は、運用フェーズと開発フェーズの両方で使用できるように設計されています。これは、軽量のプロファイリング機能とコマンドライン JDK ツールを統合したビジュアル ソフトウェアです。

VisualVM は、Java 1.4 以降で実行されるアプリケーションを監視し、JMX、jvmstat、Attach API、Serviceability Agent などのいくつかのテクノロジを使用してアプリケーションのトラブルシューティングを行います。このツールは、品質エンジニア、システム管理者、エンドユーザーのさまざまな要件に完璧に適合します。

リモートおよびローカルで実行されている Java ベースのアプリケーションを自動的に検出し、一覧表示します。このツールを使用すると、JMX 接続を使用してプログラムを手動で定義することもできます。すべてのプロセスについて、PID、渡された引数、JDK ホーム、メインクラス、JVM フラグ、JVM バージョン、システムおよび引数のプロパティなどの一般的なランタイム データが表示されます。

VisualVM は、アプリケーション内の CPU 使用率、ヒープ、メタスペースまたは永続世代メモリ、実行中のスレッド、およびロードされたクラスを監視します。実行中のすべてのスレッドを、スリープ時間、実行時間、パーク時間、モニター時間、待機時間を集計してタイムラインに表示します。

インストルメンテーション プロファイラーとサンプリング プロファイラーはどちらも、メモリ管理とアプリケーション パフォーマンスのために VisualVM を使用して実行できます。スレッド ダンプを表示して、プロセスについての迅速な洞察を提供します。また、オンデマンドで .hprof スナップショットを表示および作成して、ヒープ使用の非効率性を明らかにし、メモリ リークをデバッグするのに役立ちます。

さらに、VisualVM は、クラッシュした Java ベースのプロセスとその環境に関する基本データを読み取ることができます。アプリをオフラインで分析できます。取得したヒープ ダンプ、スレッド ダンプ、プロファイリング スナップショットを含むアプリのランタイム環境と構成を保存し、後の段階でオフラインで処理できます。

Windows、Linux、Unix で動作します。

オービットプロファイラー

Orbit Profilerを使用して C/C++ アプリケーションを視覚化し、パフォーマンスの問題をすばやく見つけます。これは、開発者が複雑なアプリの実行フローを表示して理解できるようにすることを目的としたデバッグ ツールおよびスタンドアロン プロファイラーです。

アプリ内で起こっているすべてを明確に把握できるため、パフォーマンスのボトルネックをすぐに解消し、アプリケーションの高いパフォーマンスを復元できます。

Orbit Profiler は、PDB ファイルにアクセスできれば、あらゆる C または C++ アプリで効率的に動作できます。次に、プログラムのダウンロードが完了すると、プロファイリングが開始されます。このツールはターゲット プロセスにジャンプし、選択された関数に自身をフックして、プロファイリングを実行します。

最適化された最終ビルドや出荷ビルドでも機能します。 Orbit Profiler は、動的な計測とは別に、高速で常に利用可能で堅牢な「常時オン」サンプリング機能も提供します。

Windows と Linux で動作します。

Uber JVM プロファイラー

高度なプロファイリング機能を備えたUber JVM Profiler も、Java ベースのアプリケーションに適したオプションです。

これは、分散方式で Spark/Hadoop JVM プロセスのいくつかのスタック トレースとメトリクス (メモリ/CPU/IO メトリクスなど) を収集する Java エージェントを提供します。

このツールは、ユーザー コード上の Java 引数とメソッドを変更せずにトレースできます。これを使用して、すべての Spark アプリの HDFS ネーム ノードの呼び出し遅延を追跡し、問題を見つけることもできます。 Spark アプリの HDFS ファイル パスをトレースしてホット ファイルを見つけて、さらなる最適化を実行することもできます。

Uber JVM Profiler は、もともと、一般に 1 つのアプリケーションに多数のマシンまたはプロセスを含む Spark アプリをプロファイリングするために作成されました。したがって、これらのマシンまたはプロセスのメトリクスを簡単に関連付けることができます。

ただし、このツールは一般的な Java エージェントとして機能し、任意の JVM プロセスに使用できます。その特徴は次のとおりです。

  • Java ヒープ メモリ、ネイティブ メモリ、非ヒープ メモリ、バッファ プール、メモリ プールなどの Spark アプリ エグゼキュータのメモリ使用量のデバッグ
  • CPU 使用率とガベージ コレクション時間のデバッグ
  • Java クラス メソッドの頻度と時間または期間プロファイリングをデバッグする
  • 引数プロファイリング (Java クラスのメソッド呼び出しとその引数の値のデバッグとトレース)
  • CPU 時間のスタックトラック プロファイリングとフレームグラフの生成
  • I/O メトリックと JVM スレッド メトリックのデバッグ

トレーシー

Tracy は、開発者が PHP プログラムを簡単にデバッグできるようにする便利なツールです。使いやすいデザインと、CLI サポート、AJAX 呼び出しのデバッグなどの高度な機能を備えています。

エラーを迅速に見つけて修正し、変数をダンプし、エラーをログに記録し、メモリ消費を視覚化し、クエリやスクリプトの実行時間を判断することができます。色分けを使用し、明確な説明とともに問題を赤で強調表示すると、例外やエラーを簡単に視覚化し、理解するのに役立ちます。

Tracy には、ログ機能と環境の自動検出が付属しています。データをログ ファイルに保存し、ダウンタイム中に訪問者にサーバー エラー メッセージを表示します。 Tracy は、Drupal 7、OpenCart、WordPress などと統合することもできます。

vprof

vprofは、Python アプリケーション用のビジュアル プロファイラーです。メモリ使用量や実行時間など、Python プログラムのさまざまな特性を豊富でインタラクティブに視覚化します。

BSD ライセンスの下で利用でき、Python 3.4 以降をサポートします。

結論

アプリケーションのパフォーマンスは、エンドユーザーの期待を満たすための重要な要素です。また、パフォーマンスの問題が発生した場合は、エンドユーザー エクスペリエンスに影響を与える前に問題を診断する準備ができている必要があります。

したがって、アプリケーションの最適化を継続し、問題をすぐに修正して、この記事で説明したツールを使用して超高速のアプリケーション パフォーマンスをユーザーに提供し続けてください。

以下は、上記のプロファイラーとその主な用途を示す簡単な比較表です。

名前言語
スパイ、スパイパイソン
パイロスコープPython、Ruby、Go
バブルプロフNode.js
ピンインストゥルメントパイソン
XデバッグPHP
SPX PHP
プレフィックスPython、.NET、Java、Node.js、Ruby、PHP
不等辺角パイソン
VisualVMジャワ
オービットプロファイラーC、C++
Uber JVM プロファイラージャワ
トレーシーPHP
vprofパイソン

「13 アプリケーションのパフォーマンスの問題をデバッグするためのソフトウェアのプロファイリング」についてわかりやすく解説!絶対に観るべきベスト2動画

2023年、知っておきたいWebのこと ~フレームワーク・Web UI~【CADC2023】
Meta Quest 2 で楽しむ PLATEAU VRアプリケーションの開発(2022年度PLATEAU Hands-onアーカイブ動画)