どの時点でパフォーマンスについて考える必要がありますか?


16

アプリケーションを構築しているとき、これが特定の機能を実行または実装する最良の方法であるかどうかを常に問いかけています。多くの場合、パフォーマンスに関する「馬の前にカートを置く」べきではないというコメントを受け取るために、stackoverflowまたはフィードバックを希望する別のフォーラムに質問を投稿します。ほとんどのプログラマーは、アプリケーションが終了するまでパフォーマンスについて本当に考えないのでしょうか、それともパフォーマンスがまったく許容できないのでしょうか?? つまり、開発環境は本番環境とは異なり、開発用ラップトップからの結果に完全に依存するべきではないことを理解しています...しかし、他のものよりも優れたパフォーマンスをもたらすプラクティスとテクニックがあります。

開発プロセス全体でパフォーマンスを考慮することは悪い習慣ですか?パフォーマンスが実際に低下するまで、これらの考慮事項をオフにする必要がありますか??

更新

明確にするために、機能の一部を検討している、または作業しようとしている状況について説明しています。実装にはいくつかの方法がありますが、各実装がどの程度拡張できるかはよくわかりません。また、よく知らないテクニックもいくつかあります。小規模ではいずれのアプローチでもおそらく適切ですが、大規模では一部のアプローチが維持され、一部は維持されません。多くの場合、私が意見やガイダンスを求めるとき、応答は次のとおりです。後で心配する...


私はいつもひどくスケーリングするまったくのでたらめを書かないようにします。スタートアップコードのこの完全に明確な行が、ひどくマングルされた「最適化された」バージョンよりも少しのCPUサイクルを要するかどうかは気にしません。どのような「パフォーマンスについて考える」のですか?

Daaaahling、それは明らかではありませんか?オーディションを待っているとき!
マットエレン

回答:


24

パフォーマンスに関する考慮事項の延期は、次のフレーズの誤用に基づいている場合があります。

早すぎる最適化はすべての悪の根源です。

完全な引用を読むと、Knuthが言おうとしていることは、プロファイリングなしの開発中に適用されるマイクロ最適化は、実質的なパフォーマンスの利点を必ずしも達成せずに保守性の低いコードにつながるため、一般的にお勧めできません。

しかし、それは、アプリケーションがほぼ終了するまでパフォーマンスを考慮すべきではないという意味ではありません。それを行うと、パフォーマンスが不十分であることがわかり、デザインアーキテクチャがより良いパフォーマンスをサポートしていないため、最初からやり直す必要があります。

難解な(および時期尚早な)最適化を行わずに、開発中に良好なパフォーマンスを達成するためにできることがいくつかあります。

  1. 賢明でよく考えられたアーキテクチャを使用してください。
  2. データ構造を適切に使用してください。
  3. 適切に機能するテクノロジ(ライブラリ、フレームワーク)を使用します。

これらのことを行うと、発生する必要があるパフォーマンスの最適化はコードのごく一部に限定されることに気付くでしょう。プロファイリングにより、そのコードが識別され、保守性を犠牲にすることなく、パフォーマンスの向上に焦点を当てることができます。


5
賢明でありながら使い古されたフレーズを、賢明な方法で実用的な方法で照らすために+1。問題を解決する前に、それをコーディングする前に、問題に対する優れた解決策を考えない努力の根拠として毎日使用しているため、ワークステーション上でそのフレーズをサンプラーにつなぎ合わせるプログラマーが非常に多いことを知っています。 。
アダムクロスランド

@アダム-ありがとう!同意します!私は個人的に、たくさんのコードを書く前に物事を考えることに努力をしたくない理由を理解していません。
コグニトニック

3ポイントに対して+1。これらはすべて、終了時にシステムに固定され、パフォーマンスの最適化に多大な貢献をします。すべてが終了した場合、その増加は得られません。また、一部の人々はこの引用を怠けの盾として使用していることにもアダムに同意できません。
ゼクタチャン

20

考えないことは次のとおりです。

  • ある++iよりも速くi++
  • あるswitchよりも速くif
  • inline私の機能が必要ですか?
  • 仮想機能は遅いですか?
  • C ++ / Java / C#は他のものより高速/低速ですか?
  • 何とか、何とか...

考えるべきことは次のとおりです。

  • 予想される現実的なワークロードとは何ですか?
  • 入力情報はどのくらいの頻度で変更され、誰がそれを提供しますか?プリコンパイルを検討するのは理にかなっていますか?
  • データ構造をできる限り単純化し、可能な限り正規化しましたか?それは、ハッシュなどのことを心配しないことを意味します。
  • 私が保持している通知を最小限に?(データ構造が正規化されていないため、データのある部分の変更が別の部分の同じ時間の変更を必要とする場所です。)

後者の点に関して、私の経験では、データ構造を設計して、非正規化する必要がある場合、一時的な不整合を許容できるようにすることが最善です。パフォーマンスの大きなキラーは、通知がさらに通知をトリガーするときです。これは、事前に推測することのなかった範囲で、さらにトリガーします。そして、多くの場合、自己キャンセルの変更のために無駄な努力です。

これをすべて完了したら、きれいなデザインになります。その後、定期的にプロファイルを作成します。(ランダム一時停止は、私が頼りにしている方法です。)そして、より洗練されたアルゴリズムを導入することでパフォーマンスが改善されることがわかるなら、ぜひそうしてください。


2
いい答え; 質問があまりにも早くCWに送られたのは残念でした。これが発生した理由と理由を示すために、編集履歴に監査証跡がありました。今では、SEネットワークがひそかにそれを行っているようです。
ロバートハーベイ

@ロバート:ええ。悲しい。私はちょうど私の仮想ビールに叫びに行く必要があるでしょう:-)
マイクDunlavey

3

いいえ、最初からパフォーマンス(特にデータベースの設計)について考える必要はありません。最適化は時期尚早な最適化であると考える人々によって、業界に多くの害がありました。この引用は元々、問題が発生する前に人々がマイクロ最適化を見るのを防ぐことを目的としていました。最適化をまったく行わないことを意図していませんでした。たとえば、データベースには、パフォーマンスの低い既知の技術が多数あります。設計でそれらを回避することは、あなたがする必要があることの一部です。性能の低いテクニックを使用して設計されたデータベースを100,000,000レコードでリファクタリングすることは非常に難しく、より良いハードウェアを購入することで問題を回避することはできません。


3

最初に正確性1を心配し、次に保守性、次に安全性と信頼性を心配し、次にパフォーマンスについて考えることができます。開発中に、この順序を各コードに適用します。パフォーマンスの高いソリューションは、単純に物事を明確かつ単純に保つことから自然に脱落する可能性があります。

パフォーマンスの80%が、当面の問題に適したアルゴリズムとデータ構造を選択しています。最適化が不十分なクイックソートは、平均的な場合(最悪の場合は引き分け)に、高度に最適化されたバブルソートよりも優れています。

SOの全員が「高速化、++ pまたはp ++」という考え方で、人々がコンパイラーの裏をかくのに巻き込まれ、より大きな問題を追跡できなくなるため、コードが壊れやすくなります。 -乗った、間違った、そして何よりも、より単純なソリューションよりもずっと速くなかった。私はこの種のコードを直接扱ってきました。1つの例は非常に脆いので、完全に破壊しないと変更を加えることができませんでした。


1ここで、「正確性」とは「仕様の実現」を意味し、「バグのない」と同義ではありません。


1
一部の仕様ではパフォーマンス要件が定義されていますが、注文にどのような影響がありますか?
ベンL

@ベン:理想的には、なし。ただし、上記の順序を満たしてもハードパフォーマンス要件を満たせない場合、最初のステップは、ボトルネック(duh)を見つけるためのプロファイル作成です。その後、それは判断の呼び出しです。保守性、安全性、または信頼性を犠牲にしますか?万能のソリューションは考えられません。私は安全性と信頼性についてもっと妄想しているので、おそらく最初に読みやすさを犠牲にしますが、ランタイム環境自体は他の2つを十分に安全で安定している可能性があります。
ジョンボード

2

「良い」パフォーマンスとは何かを理解したら、パフォーマンスについて考え始める必要があります。つまり、次のしきい値が何であるかを特定する前に、パフォーマンスについて考え始めるのは間違っています。

  • 許容できないパフォーマンス-手に負えなくなる前に修正する
  • 許容可能なパフォーマンス-パフォーマンスでこれ以上やろうとする前に、他の機能に注目する時です。
  • 目標のパフォーマンス-理想的なパフォーマンスの数値。つまり、十分な時間とリソースがある場合、システムで何をする必要がありますか?

これらのしきい値が何であるかを特定したら、パフォーマンスの測定に使用しているメトリックも特定しました。これは、1日に数回実行できる自動パフォーマンステストを設定できることを意味します。良くなっているか悪くなっているかがわかります。

これらのメトリックを思い付くには、システムが何をする必要があるかを理解する必要があります。たとえば、絶対パフォーマンスメトリックは(X時間以内の応答)が必要ですか、スループット測定は(Y時間ごとにX応答)が必要ですか?スループットと絶対時間の最適化には異なるアプローチが必要であり、本当に重要なことを知らない場合、間違った方法で最適化する可能性があります。


1

おそらく、時期尚早な最適化がすべての悪の根源であると聞いたことがあるでしょう。問題は、何が時期尚早になるのかということです。私の意見では、パフォーマンスについて考えることは決して悪い考えではありませんが、コードが機能するまで過度に心配しないでください。動作したら、重負荷テストを行い、ボトルネックのプロファイリングと識別を行い、パフォーマンスの最適化を行います。

そうは言っても、実際の違いを生む特定のテクニックを知っていれば、最初のコーディング段階でパフォーマンスについて考えることは何の問題もありません。たとえば、ライブラリから別のストレージ構造を選択すると、過去の経験から、一方のストレージ構造が他方のストレージ構造よりも高速/少ないRAMを使用していることがわかります。または、知っているデータ用の単純なキャッシュシステム(後のテストで必要な場合は、より洗練させることができます)を構築します頻繁にアクセスされ、キャッシュが改善されます。この方法では、パフォーマンスについてあまり心配していません(少なくとも最初はそうではありません)が、他のプロジェクトから学んだヒントやトリックを使用しています。これらを初期開発中に簡単に含めることができるように、これらをシンプルに保つようにしてください。また、いくつかの利点もあります。


1

パフォーマンスは、要件ドキュメントのシステムおよびユーザー関連の仕様で詳述する必要があります。多くの人が、アプリケーションの開発で要件分析を行うという考えに冷笑していることを知っていますが、驚くべきことに、そのようなドキュメントは、アプリケーションが完成に近づくにつれて、パフォーマンス関連のリソースをどこにどこに捧げるべきかを簡潔に答えます。そして、それはタイムリーにその質問に答えます

要件の文書化は、そうでなければ本質的でないプロセスで無駄になる何百時間もの時間を節約します。


1

バランスのとれたアプローチの方が良いでしょう。パフォーマンスは重要ですが、物事を成し遂げるほど重要ではありません。

  1. 最初に、自分のやっていることや自分のやっていることについて少し考えようとする機能を構築します(パフォーマンスについては少し考えますが、それほど多くは考えません)
  2. 試して
  3. 一度実行すると、実際に改善する必要があるかどうかを検討し始めます(通常は不必要ですが、場合によってはそうすることもあります)。

これはパフォーマンス対機能に対する私の一般的なアプローチであり、一般的な場合はすべて、プログラムの動作と、物事をより良くする必要があるかどうか、そしてどれだけ時間がかかるかを検証することに依存します。

このようなQ&Aのウェブサイトについて考えてみましょう。その背後にあるものは、質問と回答をできるだけ多くの時間/費用のパフォーマンスにする方法について、きっと多くのことを考えたと思います。しかし、通知について考えるとき、通知がたまに表示されて新しい答えや何かがあることを通知するかどうかはそれほど重要ではありません。


1

パフォーマンスについて考えることを安全に延期する方法の1つは、可能な限りドメイン固有の言語を使用することです。

開発の大部分を独自の小さなDSLで実行でき、問題のドメインを最も一般的で高レベルの形式で表現できるように十分に設計されている場合、最初に作業プロトタイプを取得することができます。実際の問題ドメインコードではなく、DSLの実装を改善するだけです。

veiwの保守性の点からも、はるかに優れたアプローチです。


1

パフォーマンスを考慮する必要があります。ただし、チューニングの終了を示すために線を引く必要があります。これは(通常)コンピューターよりもあなたの時間が重要だからです。

パフォーマンスに関する非常に優れたテキスト記事は、「コンピューターパフォーマンスシェルゲーム」です。

「ボトルネックを見つける」とも呼ばれるコンピューターパフォーマンスシェルゲームは、常に次の4つのリソース間で実行されます。

  • CPU
  • ディスク
  • 通信網
  • 記憶

任意の時点で、コンピューターはこれらのリソースのいずれかで何らかの操作が完了するのを待っています。しかし、CPU、メモリ、ディスク、またはネットワークのどれですか?パフォーマンスに興味がある場合、まず最初にやらなければならないことは、これらのボトルネックのどれが現在パフォーマンスを妨げているかを判断し、それを排除することです。


0

「最良の」方法は非常に負荷の高い用語であり、答えは実行時までわからない要因に大きく依存する場合があります。

  • 十分なメモリがありますか?-「all-in-memory」データ構造を使用するとパフォーマンスが向上しますが、十分なメモリスワッピングがない場合はパフォーマンスが低下します。
  • 永続性が必要ですか?データベースは整合性を提供しますが、上記の「オールインメモリ」データ構造よりも低速です。 かなり遅い。
  • 結果をキャッシュできますか?ワニスはそれを助けることができます! http://www.varnish-cache.org/

リストは延々と続く。

あなたができることは、あなたが現在持っている知識から「おそらく動作する可能性のある最も単純なもの」を書き、それをモジュラー形式で実行することです。「最も単純な」ことは必ずしも単純ではないことに注意してください!


0

それは常にあなたが心に留めておくべきものです。ほとんどの人が言おうとしていることは、壊れているとさえ知らないものを最適化しようとして2日間を費やすことはあまり意味がないということだと思います。製品を実行して、ユーザビリティテストを実行できるようになると、パフォーマンスの問題が発生している場所がわかります。次に、実際のパフォーマンスの問題を特定できたら、実行する必要がある最適化をターゲットにできます。


0

少なくとも理論的には、ベータテストを開始してからではなく、パフォーマンスについて考え始める必要があります。

ただし、これは設計上の決定を下すためのライセンスではありません。たとえば、NVARCHAR文字列を主キーとして使用すると、パフォーマンスが低下する可能性があります。とはいえ、パフォーマンスの問題に関係なく不潔な習慣なので、そもそも使用すべきではありません。

デザインが従来のベストプラクティス(第3正規形のすべて、クラスに隠れている適切な情報、シングルトンの最小限の使用など)に従っていて、後でパフォーマンスの問題が発生する場合は、簡単に処理できます(ここでインデックスを作成し、そこにキャッシュを実装します)。

HTH


0

場合によります。80/20ルールを念頭に置いておくと便利です。アプリケーションのコードの大部分(たとえば80%)は、パフォーマンスに顕著な違いを生じさせるほど頻繁に実行されることはありません。アプリが実行時間の約80%を費やすことになっている残りの20%に集中する必要があります。

あなたは識別することができるかもしれいくつかのように使用すると、特定の計算は倍以上の何百万人を反復されようとしていることを知っているかのように、事前に明らかにパフォーマンスのホットスポットのを。そのような場合、ジョブに適したデータ構造とアルゴリズムを選択することで事前に最適化することを検討する価値があります。

ただし、その最適化はより多くの設計作業です。通常、価値のないものは「最適化」であり、誰かが「パフォーマンスを獲得する」という名の巧妙なビットいじりのトリックで途方もない時間を費やします。特に、前後に適切な測定なしで行われた場合、そのような変更は何の違いももたらさないか、実際の環境下でアプリを実際に遅くします。


0

開発のどの段階にあるかによります

1)ソフトウェアの機能を構築する場合は、機能を維持し、正常に動作することを確認してください(つまり、望ましい効率的)。

2)ビルディングブロックが統合されると、リソースを大量に消費するヒントが得られます。最適化の余地があります。


0

パフォーマンスについて考え始める必要がある場合、問題が発生しています。常にパフォーマンスについて考える必要があります。実際、優れたプログラマーは、「男性は7秒ごとにセックスを考える」というやり方で、意図していなくてもパフォーマンスについて考えているのではないかと思います。

重要なのは、すべてのその思考に基づいて、あなたがとる行動です。思考は安上がりですが、行動はコードを破り、期限を守ることができます。

ほとんどの場合、唯一の賢明なアクションは何もしないことです。あなたは、パフォーマンスの問題を観察するのに十分な頻度でコードの一部が呼び出されないことを特定しました。潜在的なユーザーベースの1%。多分、データベースアクセスの遅い海でdrれた冗長なサーバーコードのほんの一部であり、コードの非クリティカルセクションでの単なる整数の割り当てかもしれません。

多くの場合、特定の操作によってパフォーマンスの問題が発生する可能性がありますが、これは簡単な変更で解決できます。たとえば、すべてのリクエストで複雑なSQLクエリを実行したり、辞書から同じデータを2回要求したりすることは、あなたにとって悪いことだと感じています。これは、最適化技術の知識が役立つ場所であり、おそらく最も驚くべき結論が起こります:

コードの一部のパフォーマンスをほぼ確実に向上させる簡単な手法を知っている場合は、実行しないでください。

今考えることができれば、5分後には確かにそれを行うことができます。コード内に(ただし、おそらく// TODOコメント内に)残しておくと、コードがきれいになり、後で別の機能で作業する時間を節約できます。そのコードを後で破棄しても無駄になりません。テスト時に元のコードがパフォーマンスの問題を引き起こすことが判明した場合は、戻って簡単なテクニックを適用してください。

ここでは、たまたま高速であるという理由だけで、慣用的なコードを書くことを避けるべきだとは言っていません。生産性と読みやすさを改善し、バグを減らすベストプラクティスに従って慣用的なコードを記述します。慣用的な定型のコードと、より高速でありながら簡単に書かれた代替案のどちらかを選択できる場合は、常に速度ではなく読みやすさを追求してください。

唯一の困難な状況は、コードのパフォーマンスを改善する簡単な方法がないように思えるのに、コードが配信されるとすぐに壊れてしまうことは痛いほど明白です。サイトのページごと、または同様に恐ろしいもの。これは、実際に停止し、さらに考える必要がある場所です。これらは通常、ローカルの規模では解決できないアーキテクチャの問題です。簡単なスパイクまたはプロトタイプで疑念を確認し、同様の経験と一般的なソリューションを探し、アーキテクチャの変更または機能のドロップを検討します。


0

私見では、システムを実装する前にパフォーマンスについて考えることが重要ですが、考えてみてください。アプリケーションを分析し、潜在的なパフォーマンスのボトルネックになる可能性のあるものを見つける必要があります。

次に、システムをできるだけシンプルに実装します。パフォーマンスの問題が発生した場合は、最適化してください。

たとえば、ある種のサービス(SOAP、REST HTTPなど)を介してデータを取得するGUIクライアントがあるとします。それから、高いパフォーマンス/スケーラビリティのための最も重要なことは、できるだけ少ない呼び出しを持ち、各呼び出しが多くのデータを返すようにすることです。

この種のシステムを実装するとき、システム間の呼び出しの数はそれほど気にしません。ただし、必要に応じてコードベースを使用すると、リファクタリングや最適化が容易になります。


0

パフォーマンスについては、最初から非常に一般的な方法で考える必要があります。アプリケーションに適した、効率的なデータ構造とアルゴリズムを選択する必要があります。アルゴリズムはソフトウェアの基本であり、データ構造はさらに重要です。どちらかを大幅に変更する必要がある場合は、大規模な書き換えが必要になる可能性がありますが、小さな詳細はより簡単に書き換えることができます。

効率的な習慣を身につけたいかもしれませんが、これらは言語に依存します。C ++では、たとえば、「++ i;」スタンドアロンのステートメントまたは式は常に少なくとも「i ++;」と同等であり、潜在的にははるかに効率的です。ただし、ほとんどの場合、明確なコードを記述し、コンパイラを信頼する必要があります。微小効率を心配する習慣を身に付けると、ほとんどの場合、解決するよりも多くの問題が発生します。デスクトップアプリの場合、コンパイラは少なくともi >> 1vs. などと同じくらいスマートi / 2であるか、パフォーマンスを改善する最良の方法はより良いコンパイラを取得することですので、心配しないでください。

それを超えて、テストできるものを手に入れるまで心配しないでください。その時点で、プログラムをプロファイリングしてホットスポットの場所を確認し、パフォーマンスプログラムがあるかどうかについてのアイデアを得ることができます。パフォーマンスを改善する必要がある場合は、プログラムがその時間のほとんどを費やしている場所を見つけて、そこを改善してください。十分なグローバル効率で設計し、プログラムを適切に作成した場合、プログラムの比較的小さな部分を変更するだけです。


0

あなたができる最善のことは、何かが機能するまで、良い設計慣行に従うことです(例えば、パフォーマンスを妨げるとわかっていることをしないでください)。改善を測定できない場合、改善を行うことはできません。テストできるものが得られたら、プロファイリングを実行して、ホットスポット(存在する場合)の場所を把握することをお勧めします。何かが飛び出した場合、問題領域のリファクタリングまたは書き直しを検討する必要がありますが、それがそれほど悪くない場合(コードが2つまたは3つのメソッドでその時間の90%を費やしているからといって、全体的に適切に実行されていれば何の意味もありません)その後、開発を続けます。私が何度も見たのは、システムの最も複雑な部分を最適化するのに何日も費やす開発者です。


0

いつそれについて考え始めるべきですか?どのくらいの労力を費やすべきですか?それはプロジェクトのコックバーンスケールに依存します。(言い換えると、パフォーマンスが良くないリスクは何ですか?)

基礎を十分に事前に学習してください(Robert Harveyの回答を参照)。ソフトウェア開発のさまざまな段階でパフォーマンス指向の思考を適用するために、開発者はそれを裏返しに知っておく必要があります。そのため、思考プロセスがこれらの余分な考慮事項によって妨げられません。(言い換えれば、プロジェクトが着想される前にパフォーマンスについて考え始めてください。)

開発の初期段階で、パフォーマンスプロファイリングツールを自由に使用し、統計履歴を追跡します。これらの情報を整理して、後の意思決定に役立つように特に注意してください。

次に、プロジェクトの性質とCockburn Scaleに応じて:

  • ラピッドプロトタイピング、または「明日はないようなコードをバンギング」、またはビジネスへの影響が少ない社内開発:統計を保持するだけです。パフォーマンスについてはまだ考えないでください。最も簡単な方法で関数を実装します。頭に浮かぶ最初のアルゴリズムに固執します。

    • プロジェクトの後半では、実際の使用事例に基づいて「ホットスポット」を特定するためのアドホックパフォーマンステストが行​​われます。ソフトウェアを使用できなくするパフォーマンスの問題がある場合、簡単に識別できるはずです。
    • ビジネスへの影響が少ない社内開発の場合は、コードを展開して、パフォーマンスの問題を後で修正するだけです。
  • デスクトップアプリケーション。パフォーマンスへの一貫したバランスの取れたアプローチが必要です。高度に最適化する必要はありません。ただし、「ハング」(非応答性)はできるだけ少なくする必要があります。

    • 通常、デスクトップアプリケーションには非常に複雑な実行パスがあり、パフォーマンス指向の思考を複雑にします。階層化された設計により、データベースのパフォーマンスの問題とGUIのパフォーマンスの問題を分離し、チームのさまざまな専門家が対処できます。
    • ログトレースの履歴により、ホットスポットを特定できます。
  • ハイパフォーマンスコンピューティング。ハードウェアを最大限に活用する必要があります。

    • パフォーマンス統計の分析と報告を担当するチームの誰かを任命してください。
    • パフォーマンス特性に関する理論を作成し、実験で検証し、単純化されたコンプSciモデルからの予測と比較します。
    • *

0

初めに。必要なパフォーマンス特性を特定します。ターゲットを特定できない場合は、要件をよりよく理解するために後退するか、コンポーネントの要件が書き直される可能性があるリスクを知るまで延期する必要があります。次に、テストします。最適化しないで、テストします。コードがパフォーマンステストに失敗した場合は、最適化します。適切なテストフレームワークを使用して、既存のパフォーマンス監視ツールを使用すると、タスクがかなり簡単になります。

プロジェクトの存続期間中は、回帰テストとしてパフォーマンステストを実施してください。メンテナンスコードは、パフォーマンスの問題を引き起こすことで有名です。これは、「修正」が非常に狭い焦点に当てられることが多いためです。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.