web-dev-qa-db-ja.com

アプリケーションのボトルネックを見つける方法は?

私は多くのコンポーネントを含むアプリケーションを構築しています。それらの多くはサードパーティなので、ドキュメントから何が得られるかしかわかりません。

時々、純粋な運により、これらのコンポーネントの1つがかなり重く、キャッシュするオプションがあったことがわかりました。

運が悪ければ、これらのコンポーネントの1つがアプリのパフォーマンスを低下させてしまい、どうすればいいのかわからなくなると考えるのをやめられません。私は馬鹿のようなハードウェアを追加することになります。

では、どのようにしてこの種のボトルネックを見つけるのでしょうか。つまり、データベースで発生するような「この部分は遅い」という素敵なレポートはありません。

たとえば、今日使用していたシリアライザが重く、キャッシュされていないことがわかりました。シリアライザーが物事を遅くしていることを発見するために私が従うことができた反復可能なステップはありますか?

10
ChocoDeveloper

従うべき2つの道があります。

  1. 盲目的に直感に従ってください。

  2. アプリケーションプロファイラーを取得します。

長所と短所を見てみましょう。

盲目的に直感に従ってください

これは:

  • 低い資本コスト(ハンチは無料)
  • 非常に簡単に計測できます(計測機能はありません)。
  • プログラミングの経験に大きく依存して問題を確認する
  • 問題を見つけるのはあまり正確ではない
  • 驚くほどの時間を消費するウサギの穴を作成するのに最適ですが、一般に測定可能な改善はあまりありません。 (測定していることを前提としています)

アプリケーションプロファイリング

  • 通常、取得コストがあります。本当に良いプロファイラーは高価になる可能性があります
  • アプリケーションのパフォーマンスの測定値を提供します。より良いものは、
    1. 最も多くの時間を消費する
    2. 通話量が最も多い
  • アプリケーションをインスツルメントできるようにするか、少なくとも懸念されるユースケースを手動で実行できるようにする必要があります。
  • 大量の情報で溢れる可能性があるため、何を探すべきかを理解する必要がある

アプリケーションの大きさに応じて、ブラインドハンチを追跡し、実時間に依存するか、コードでいくつかのDateTime呼び出しをスローして、実行にかかる時間を追跡できます。私は個人的に24時間以上のランタイムのアプリケーションをいくつか取り、このアプローチを使用してそれらを15分と1〜2時間に減らしました。しかし、それらは小さなアプリケーションであり、関係するすべてのコードを理解できました。

一方、私はプロファイラーを数回使用して、非常に大きなアプリケーションを作成しました。最も懸念されるユースケースを再現できるようにする必要があり、これは面倒な場合があります。長いプロセスを手動でステップ実行すると、問題が発生する可能性があります。しかし、私はこれらのツールを使用してバックグラウンドの起動プロセスを追跡し、これらのアプリケーションのパフォーマンスを大幅に向上させることができました。

一部のプロファイラーを見つけるには、「your_language +プロファイラー」を検索すると、かなりの数のオプションから選択できます。


コメントまでフォローアップ:

  1. Mason Wheelerは、一部の優れたプロファイラーは安価である可能性があることを正しく指摘しています。提供される機能は、おそらくコストの最大のドライバーです。いくつかの点で、それは他のソフトウェア製品と同じです-コストと機能の間には相関があります。

  2. ChocoDeveloperが指摘したように、中間点がある可能性があります。独自のプロファイラーを作成することもできますが、これはかなりの時間の投資になる可能性があります。そして、あなたは盲目的な道の危険を冒します。あなたが知っている問題がMyModule.Foo()にある場合、次のことができますModule2.Bar()の問題に気付かない。ただし、そのリスクを認識している場合は、すべてのプロファイルを確実に作成できます。

    • このように、測定とログの対象を非常に具体的に指定することで、軽量のプロファイラーを作成できます。優れたプロファイラーの中には、この機能を提供するものもあります。
  3. プロファイラーは製品コードで実行できます。パフォーマンスに影響があるため、通常は行われません(Doc Brownが指摘しているように)。ただし、本番環境以外の場所でパフォーマンスの問題を再現できない場合は、プロファイラーを本番環境で実行します。作成されるリスクと潜在的な問題を理解する必要がありますが、それは可能です。

  4. 私の最初の返答は、あなた自身のプロファイラーを構築することに多くの信用を与えませんでした。私の経験では、既存のプロファイラーを使用する方が、自分でプロファイラーを作成するよりも安上がりです。プロファイラーは必ずしも非常に複雑であるとは限りませんが、プロファイラーはあなたが引き受けている別のプロジェクトであり、結果を信頼する前に正しく機能していることを確認する必要があります。私が働いていた組織にとって、プロファイラーの構築はコアコンピテンシーに接するものであり、ビジネスにとって意味がありませんでした。

  5. Program Optimization に関するウィキペディアの記事をまだご覧になっていない場合は、こちらをご覧ください。その記事で引用されているいくつかの選択肢の引用を以下に示します。

「ボトルネックは意外な場所で発生するので、ボトルネックがどこにあるかが判明するまでは、2番目に推測してスピードハックを行わないでください。」 —ロブ・パイク

「プログラム最適化の最初のルール:実行しないでください。プログラム最適化の2番目のルール(専門家のみ!):まだ実行しないでください。」 —マイケルA.ジャクソン

「私たちは小さな効率を忘れて、時間の約97%を言う必要があります。時期尚早な最適化がすべての悪の根源です。しかし、その重要な3%で機会を逃さないでください。優れたプログラマーは、そのようなことに満足することはありません。推論として、彼は重要なコードを注意深く見るのが賢明でしょう;しかし、そのコードが識別された後にのみ」-ドナルド・クヌース

21
user53019

グレンの答え はかなり正確で包括的なものですが、 負荷テスト も組み合わせて使用​​したいと思います。

プロファイリングは難しく、実行するのに費用がかかる場合があります。本番環境では基本的に不可能です。しかし、さらに悪いことに、パフォーマンス管理へのアプローチ全体がプロファイリングに基づいている場合は、手遅れになるまでこれらの問題を見つけることができません。

チーム/プロジェクトが十分に管理されている場合、負荷テストが必要です。これはもちろん、継続的インテグレーションやインテグレーションテストなどのすべての前提条件がすでにあることを前提としています。優れた負荷テストは単に測定するだけでなく、ベースラインを確立するので、突然の変化や段階的な変化さえ簡単に確認できます。

負荷テストの出力に突然の変化が見られる場合は、前回のテスト実行以降に加えた変更が原因であることがわかります。負荷テストを毎日または毎週実行している場合でも、ステップをたどって、どのコミットがスループットやレイテンシの原因となっているかを突き止めることはまったく難しくありません。

負荷テストは、本番環境で問題を発見した後にはあまり役立ちません。しかし、パフォーマンスが許容レベルに達したら、パフォーマンスの問題についてfastフィードバックを得ることができるように、負荷テストソリューションへの投資を検討する必要があります。 、できればbefore特定のアーキテクチャまたは製品に固定されており、簡単に元に戻すことはできません。

8
Aaronaught

決して遅刻しないほうがいい:

では、どのようにしてこの種のボトルネックを見つけるのでしょうか。つまり、「この部分は遅い」という素敵なレポートはありません...

ここに私がそれらを見つける方法があります。

スローネスは常に「この部分」に限定されるわけではありません。そうでない場合でも、無視できるわけではありません。

追加:コメントに応えて、ビデオでそれが最もよく説明されることを望みましたが、@ gnatには良い点があります。 これについてたくさん書いた 、そしてもっと科学的な説明がある ここ

一言で言えば、たとえば、プロファイラーから(適切な場合)、壁時計時間でより多くのスタックサンプルを取得できます。多数のサンプルを使用すると、豊富な情報を任意ので表示することはできませんが、測定値の要約のみが表示されます。何を修正できるかを説明するにはあいまいすぎます。

たとえば、コードの周りに何かが分散している可能性があるため、特定のルーチンに集中していないため、修正すると、時間を20%節約できます。 10個か20個のサンプルを見ると、約2〜4個以上に現れて見えます。ただし、10000個のサンプルがある場合、2000個以上がそのアクティビティを実行しますが、表示されるのはルーチンの時間測定だけなので、問題は発生しません。

StackOverflowには、「このプロファイラーの出力は何を意味するのか」という形式の質問がたくさんあります。したがって、多くのプロファイラー出力に対する一般的な応答は、「これは何ですか」です。またはそのいとこ「このコードを高速化する方法はありません」。

実際には、少数のサンプルを詳細に調べた場合に表示される方法があります。

それはあなたがそれらすべてのサンプルに対して支払う価格です。

4
Mike Dunlavey

パフォーマンスのチューニングは、どのリソースが実行時間またはスループットにとって実際に重要であるかを観察することによって導かれる必要があります。マルチユーザーマルチプロセッシングシステムでは、これを汎用プロファイラーで評価することは困難であり、アプリケーションのタイプに大きく依存します。

次の手順は、必要なだけ頻繁に実行する必要があります。

  1. 目標とする時間やスループットの観点からパフォーマンス目標を定義します。

  2. 過負荷のリソース(CPU、RAM、Lan、グラフィックスボード、個別のデータベース、プロセス/ハンドル...)を特定します。

  3. 過負荷が発生する理由を調べます。

  4. 負荷を軽減するようにアプリケーションを変更してください。

  5. 2.目標に到達するか、時間予算がなくなるまで戻る

PCベースのアプリケーションの場合、Microsoft/Sysinterals Process Explorer は、どのリソースがパフォーマンスを制限する可能性があるかについての概要を提供します。 topシステムの概要を確認するには、ntopiostatvmstatUnixなどのツールを使用してください。過度のページファイルトラフィックは、メモリの消費量が多すぎることを示しています。通常、Oracleなどのデータベースには、データベースの負荷の大部分を引き起こすSQLステートメントを見つけるためのツールがあります。

テスト対象のシステムに干渉する外部の影響(マルウェアスキャナーなど)がないことを確認します。結果を信頼できるものにするためにテストを繰り返します。

1つのボトルネックを解消すると、次のボトルネックが表示される可能性があります。

1
Axel Kemper