6

この用語はよく使われていますが、ほとんどの人が怠惰や無知から使っているように感じます。たとえば、私はこの記事を読んでいました:

http://blogs.msdn.com/b/ricom/archive/2006/09/07/745085.aspx

そこで彼は、自分のアプリに必要な型を実装するために行った決定について語っています。

私が書く必要があるコードについてこれらについて話しているとしたら、他のプログラマーは次のいずれかを考えるでしょう。

  1. 何もないときに先のことを考えすぎているため、時期尚早に最適化しています。
  2. スローダウンやパフォーマンスの問題が発生していないのに、取るに足らない詳細を考えすぎる。

または両方。

そして、それを実装するだけで、問題が発生するまでこれらについて心配しないことをお勧めします。

どちらがより優遇されますか?

実装が完了する前に、パフォーマンスが重要なアプリケーションの時期尚早な最適化と情報に基づいた意思決定を区別する方法は?

4

10 に答える 10

13

次の場合、最適化は時期尚早です。

  1. あなたのアプリケーションは、タイム クリティカルな処理を行っていません。(つまり、ファイルに 500 個の数値を追加するプログラムを作成している場合、「最適化」という言葉が頭に浮かびません。時間を無駄にするだけだからです。)

  2. アセンブリ以外の何かでタイムクリティカルなことを行っていて、それi++; i++;がより速いかどうかをまだ心配しi += 2ています...それが本当にそれほど重要な場合は、アセンブリで作業していて、これについて心配する時間を無駄にしません. (それでも、この特定の例はおそらく重要ではありません。)

  3. あるものは他のものよりも少し速いかもしれないという予感がありますが、調べる必要があります。たとえば、の方が速いか、 のStopWatch方が速いかについて何かに悩まされている場合Environment.TickCount、それは時期尚早の最適化です。なぜなら、差が大きければ、おそらくより確実であり、それを調べる必要がないからです。

何かが遅いと推測しているがよくわからない場合は、//NOTE: Performance?コメントを入力してください。後でボトルネックに遭遇した場合は、コード内のそのような場所を確認してください。個人的には、あまり明白でない最適化については心配していません。必要に応じて、後でプロファイラーを使用します。

別のテクニック:

プログラムを実行し、デバッガーでランダムに割り込んで、停止した場所を確認します。停止した場所はボトルネックである可能性が高く、そこで停止する頻度が高いほど、ボトルネックは悪化します。それはほとんど魔法のように機能します。:)

于 2011-01-28T20:23:12.847 に答える
4

最適化とは、既存のコードをより効率的に実行するプロセスです (高速化、および/またはリソース使用量の削減)。

プログラマーが最適化の必要性を証明していない場合、すべての最適化は時期尚早です。(たとえば、コードを実行して、許容できる時間枠内で正しい結果が得られるかどうかを判断します。これは、コードを実行して十分な速度で実行されるかどうかを「確認」するか、プロファイラーで実行してより慎重に分析するのと同じくらい簡単です) .

何かを適切にプログラミングするには、いくつかの段階があります。

1) ソリューションを設計し、適切で効率的なアルゴリズムを選択します

2) 適切にコード化された、保守可能な方法でソリューションを実装します。

3) ソリューションをテストし、速度、RAM 使用量などの要件を満たしているかどうかを確認します (例: 「ユーザーが [保存] をクリックしたとき、1 秒未満で完了しますか?」 0.3 秒かかる場合、実際にはそうではありません。その時間を 0.2 秒に短縮するには、1 週間かけて最適化する必要があります)。

4)要件を満たしていない場合は、その理由を検討してください。ほとんどの場合、これは、問題をよりよく理解したので、ステップ (1) に進んでより良いアルゴリズムを見つけることを意味します。(簡単なプロトタイプを作成することは、多くの場合、これを安価に調査するための良い方法です)

5)それでも要件を満たしていない場合は、ランタイムの高速化に役立つ最適化の検討を開始します (たとえば、ルックアップ テーブル、キャッシュなど)。このプロセスを推進するために、プロファイリングは通常、コード内のボトルネックや非効率性を特定するのに役立つ重要なツールです。これにより、コードに費やした時間を最大限に活用できます。

かなり慣れ親しんだ問題に取り組んでいる経験豊富なプログラマーは、このプロセスを毎回物理的に実行するのではなく、精神的に最初のステップを飛び越えてからパターンを適用することができるかもしれないことを指摘しておく必要がありますが、これは単なる近道です。経験を通して得た

したがって、経験豊富なプログラマーがコードに自動的に組み込む多くの「最適化」があります。これらは「時期尚早の最適化」ではなく、「常識的な効率パターン」です。これらのパターンはすばやく簡単に実装できますが、コードの効率が大幅に向上するため、特別なタイミング テストを行って、それらが有益かどうかを判断する必要はありません。

  • 不要なコードをループに入れない。(既存のループから不要なコードを削除する最適化に似ていますが、コードを 2 回書く必要はありません!)
  • 何度も再計算するのではなく、中間結果を変数に格納します。
  • その場で計算するのではなく、ルックアップ テーブルを使用して事前計算された値を提供します。
  • 適切なサイズのデータ​​構造を使用する (たとえば、パーセンテージを long (64 ビット) ではなく 1 バイト (8 ビット) に格納すると、RAM の使用量が 1/8 になります)
  • 個々のコンポーネントを多数描画するのではなく、事前に描画された画像を使用して複雑なウィンドウの背景を描画する
  • 帯域幅の使用を最小限に抑えるために、低速接続で送信する予定のデータのパケットに圧縮を適用します。
  • 高品質で適切な圧縮が得られる形式を使用できるスタイルで、Web ページの画像を描画します。
  • そしてもちろん、技術的には「最適化」ではありませんが、そもそも正しいアルゴリズムを選択することです!

たとえば、プロジェクトの古いコードを置き換えました。私の新しいコードは決して「最適化」されていませんが、(元の実装とは異なり) 効率を念頭に置いて書かれています。その結果、私のものは 25 倍高速に実行されます - 単純に無駄がないからです。最適化して高速化できますか?はい、さらに 2 倍のスピードアップを簡単に実現できました。コードを最適化して高速化しますか? いいえ - 5 倍の速度向上で十分だったでしょう。私はすでに 25 倍を達成しています。この時点でさらに作業を行うと、貴重なプログラミング時間を無駄にするだけです。(ただし、要件が変更された場合は、将来コードを再検討できます)

最後に、もう 1 つ重要な点があります。あなたが取り組んでいる分野によって、満たさなければならない基準が決まります。ゲーム用のグラフィックス エンジンやリアルタイム組み込みコントローラー用のコードを作成している場合、多くの最適化を行っていることに気付くでしょう。メモ帳のようなデスクトップ アプリケーションを作成している場合、無駄が多すぎない限り、何も最適化する必要はないかもしれません。

于 2011-01-29T09:54:39.260 に答える
4

このことわざは、(私が思うに) 優れた設計が作成されたときに組み込まれる最適化を指していません。それは、他の方法では実行されない、特にパフォーマンスを目的としたタスクを指します。

常識によれば、この種の最適化は時期尚早に「なる」ことはありません。無実であることが証明されるまで有罪です。

于 2011-01-28T20:25:38.337 に答える
3

開始時は、製品を提供することだけが最適化よりも重要です。

時間の経過とともに、さまざまなアプリケーションのプロファイリングを行い、最適化されたコードに自然につながるコーディング スキルを学習します。基本的に、ある時点で、潜在的な問題点を見つけて、それに応じて構築できるようになります。

ただし、実際の問題が見つかるまでは気にしないでください。

于 2011-01-28T20:24:23.823 に答える
3

時期尚早な最適化とは、コードの他のプラスの属性 (読みやすさなど) を犠牲にして、このトレードオフを行う必要があることに気付く前に、パフォーマンスを最適化することです。

通常、コードのボトルネックを見つけるためにプロファイリング ツールを使用せずに、開発プロセス中に時期尚早の最適化が行われます。多くの場合、最適化によってコードの保守が難しくなり、場合によっては開発時間が長くなるため、ソフトウェアのコストも増加します。さらに悪いことに、時期尚早の最適化によっては、コードがまったく速くならないことが判明し、場合によってはコードが以前よりも遅くなる可能性さえあります。

于 2011-01-28T20:18:23.007 に答える
1

(たくさんの)経験を持つことは罠かもしれません。私は非常に経験豊富なプログラマ (C\C++、アセンブリ) を多く知っていますが、彼らはクロック ティックや余分なビットについて心配することに慣れているため、心配しすぎる傾向があります。

組み込みシステムやリアルタイム システムなど、これらが重要な領域がありますが、通常の OLTP/LOB アプリでは、保守性、読みやすさ、および変更可能性にほとんどの労力を注ぐ必要があります。

于 2011-01-28T20:23:55.427 に答える
1

実装の初期段階で最適化の設計に時間をかけすぎると、最適化は時期尚早です。初期段階では、コア コードの実装、単体テストの作成、システム同士の通信、UI など、より良いことを心配する必要があります。最適化には代償が伴います。保守が困難なコードを作成している間、最適化する必要のないものを最適化することに時間を浪費している可能性があります。

最適化は、プロジェクトの具体的なパフォーマンス要件がある場合にのみ意味があります。パフォーマンスは初期開発後に重要になり、測定する必要があるものを実際に測定するために十分なシステムが実装されています。測定せずに最適化しないでください。

より多くの経験を積むにつれて、将来の最適化に細心の注意を払って初期の設計と実装を行うことができます。つまり、パフォーマンスの測定と後で必要になった場合の最適化が容易になるような方法で設計を試みることができます。 . ただし、この場合でも、開発の初期段階では最適化にほとんど時間をかけるべきではありません。

于 2011-01-29T00:14:24.427 に答える
1

コーディング経験が 10 年未満の場合。

于 2011-01-28T20:20:15.707 に答える
1

最適化はトリッキーです。次の例を検討してください。

  1. 両方のジョブを実行する単一のサーバーを実装するのではなく、それぞれが独自のジョブを実行する 2 つのサーバーを実装することを決定します。
  2. パフォーマンス上の理由から、別の DBMS ではなく 1 つの DBMS を使用することにしました。
  3. パフォーマンス上の理由から、標準がある場合に特定の移植性のない API を使用することを決定する (たとえば、基本的に標準の JPA が必要な場合に Hibernate 固有の機能を使用する)。
  4. パフォーマンス上の理由からアセンブリで何かをコーディングする。
  5. パフォーマンス上の理由からループを展開します。
  6. 非常に高速だがあいまいなコードを書く。

ここでの結論は単純です。最適化は広い用語です。時期尚早の最適化について人々が話すとき、全体像を考慮せずに頭に浮かぶ最初のことだけを実行する必要があるという意味ではありません。彼らはあなたがすべきだと言っています:

  1. 80/20 ルールに集中してください。考えられるすべてのケースを考慮するのではなく、最も可能性の高いケースを考慮してください。
  2. 正当な理由なしに過度に設計しないでください。
  3. 実際に差し迫ったパフォーマンス上の問題がない場合は、明確で単純で保守が容易でないコードを記述しないでください。

それは本当にすべてあなたの経験に要約されます。あなたが画像処理の専門家で、10 回前に行ったことを誰かに依頼された場合、最初からすべての既知の最適化をプッシュすることになりますが、それは問題ありません。時期尚早の最適化とは、そもそも最適化が必要であることを知らずに何かを最適化しようとすることです。その理由は単純です。リスクが高く、時間を浪費し、保守性が低下するからです。したがって、経験があり、以前にその道をたどったことがない限り、問題があることを知らない場合は最適化しないでください。

于 2011-01-28T20:34:07.657 に答える
1

最適化は無料ではないことに注意してください (ビールのように)

  • 書くのにもっと時間がかかる
  • 読むのにもっと時間がかかる
  • テストに時間がかかる
  • デバッグに時間がかかる
  • ...

したがって、何かを最適化する前に、その価値があることを確認する必要があります。

あなたがリンクしたその Point3D タイプは、何かの礎石のように思えます。最適化のケースはおそらく明らかでした。

.NET ライブラリの作成者が System.String の最適化を開始する前に測定を必要としなかったのと同じように。ただし、その間に測定する必要があります。

しかし、ほとんどのコードは、最終製品のパフォーマンスに重要な役割を果たしません。つまり、最適化の努力が無駄になります。

それに加えて、ほとんどの「時期尚早の最適化」は、テストされていない/測定されていないハックです。

于 2011-01-28T20:36:01.257 に答える