最適化が時期尚早なのはいつですか?


82

クヌースが言ったように、

効率が小さいこと、たとえば約97%の場合は忘れてください。時期尚早の最適化は、すべての悪の根源です。

これは、「最も効率的なループメカニズムはどれですか」、「SQL最適化手法」などの質問に対するStackOverflowの回答でよく出てくるものです。(など)。これらの最適化のヒントの質問に対する標準的な答えは、コードのプロファイルを作成し、それが最初に問題であるかどうかを確認することです。問題がない場合は、新しい手法は不要です。

私の質問は、特定の手法が異なっていても、特にあいまいまたは難読化されていない場合、それは本当に時期尚早の最適化と見なすことができるかということです。

これは、RandallHydeによるTheFallacy of PrematureOptimizationという関連記事です。


41
それは一種の皮肉だこと自体が途中で見積もりを最適化した「早すぎる最適化は諸悪の根源である」叫ぶ多くの人々 :(続き)
いくつかの

21
(ドナルド・クヌース):「時期尚早の最適化は諸悪の根源であるしかし、我々はその重要な3%で私たちのチャンスを逃すべきではない私たちは、時間の97%について言う、小さな効率を忘れなければならない。」
いくつか

2
これを言ったのはCAホアだったと思います。クヌースでさえそう言っています。
jamesh 2008

1
はい、トニー・ホーアは最初に「時期尚早の最適化はすべての邪悪な部分の根源である」と言いましたが、クヌースは残りを追加して彼を引用/言い換えました
nickf 2008

2
引用はほとんどの場合乱用され、文脈から外されていることに同意しますが、定義上、「時期尚早」のために常に正しいです(ただし、ずさんなデザインとコードの正当化として誤って使用されることがほとんどです)。定義上、最適化が開発の最も適切な時点で行われた場合、それが設計中であろうと他の時点であろうと、それは「時期尚早」ではありませんでした。
ローレンスドル2011年

回答:


103

Don Knuthは、コンピューターコードの最も重要な機能は、プログラマーの意図を人間の読者に伝えることであると信じていため、文芸的プログラミング運動を開始しました。パフォーマンスという名目でコードを理解しにくくするコーディング手法は、時期尚早の最適化です。

最適化の名の下に導入された特定のイディオムは非常に人気があり、誰もがそれら理解し、時期尚早ではなく期待されるようになりました。例としては

  • 使用ポインタ演算の代わりに、配列表記をそのようなイディオムの使用などを含む、Cに

    for (p = q; p < lim; p++)
    
  • 次のように、グローバル変数をLuaのローカル変数再バインドします。

    local table, io, string, math
        = table, io, string, math
    

そのようなイディオムを超えて、あなたの危険に近づいてください

すべての最適化は時期尚早です。

  • プログラムが遅すぎる(多くの人がこの部分を忘れている)。

  • あなたは持って測定することを示す(プロファイルまたは類似の)最適化が物事を改善できるし

(メモリを最適化することもできます。)

質問への直接の答え:

  • 「異なる」手法によってプログラムが理解しにくくなる場合、それは時期尚早の最適化です。

編集:コメントに応えて、挿入ソートのような単純なアルゴリズムの代わりにクイックソートを使用することは、誰もが理解し、期待するイディオムの別の例です。(ライブラリソートルーチンを使用する代わりに独自のソートルーチンを作成する場合でも、非常に正当な理由があることを願っています。)


13
あなたの定義によると; クイックソートの実装がバブルソートよりも読みにくく、理解しにくい場合、それは時期尚早の最適化です。メモリを最適化できませんか?大きなスパース行列についても同じ例を調べてみてください。私見ですが、ほとんどの最適化は設計段階で行う必要があります。つまり、非常に早い段階で。
SmacL 2008

1
@frankodwyer:ただし、ポインターをインクリメントする方が、カウンターをインクリメントして配列表記を使用するよりも高速である可能性があり、最適化が時期尚早になります。
ヨアヒムザウアー

5
@Norman:クイックソートは今やどこにでもありますが、最初に発明されたときではなかったので、QEDは、作者がビジネスをいじることのない時期尚早の最適化でしたね。
ローレンスドル

5
@Software Monkey:もちろんです。すべてのCS調査は納税者のお金の無駄であり、すぐに停止する必要があります。
ノーマンラムゼー

11
あなたが発明したものを含むすべてのソートアルゴリズムは、適切なコメント付きのsortQuickly(...)と呼ばれる別個の関数として記述されている場合、明確で簡潔です。
ilyan。

40

私見ですが、最適化の90%は、認識されている現在の要件、さらに重要なことに将来の要件に基づいて、設計段階で行う必要があります。アプリケーションが必要な負荷にスケーリングしないためにプロファイラーを取り出す必要がある場合は、手遅れになり、IMOは問題の修正に失敗する一方で、多くの時間と労力を浪費します。

通常、価値のある最適化は、速度の点で桁違いのパフォーマンスの向上、またはストレージや帯域幅の点で乗数を得る最適化だけです。これらのタイプの最適化は通常、アルゴリズムの選択とストレージ戦略に関連しており、既存のコードに戻すことは非常に困難です。それらは、システムを実装する言語の決定に影響を与えるほど深くなる可能性があります。

したがって、私のアドバイスは、コードではなく要件に基づいて早期に最適化し、アプリの可能な延長寿命に目を向けることです。


6
私はあなたの「遅すぎる」結論に同意しません。基本的に、仮定が成り立たない場合はプロファイリングが必要であり、プロファイラーはどの仮定が破られたかを通知する必要があります。たとえば、JavaのStringBuffersの「位置0の文字を削除する」は、junitテストでは正常に機能しましたが、大きな文字列では非常に遅いことがわかりました。プロファイラーがそれを犯人として特定するまで、私はそのコードを疑っていませんでした!
するThorbjörnRavnアンデルセン

7
私の経験に基づくと、「プロファイラーが必要なときはもう遅れている」ということに同意します。私のパフォーマンスの問題の大部分は、単一のボトルネックではなく、複数の貢献者に広がっています。しかし、その後、私は低レベルのコードとコストに強いバックグラウンドを持っており、最初の文字列文字の(大幅に繰り返される)削除に依存するあらゆるものを本能的に避けていただろう。「設計時に最適化」の場合は+1。
peterchen 2009年

@peterchen好奇心から、「最初の文字列文字の削除」のために何をしましたか。
ghos3t 2017年

1
@ user258365:ブルートフォースは、サブ文字列のコピーを作成する必要のない文字列表現を使用することです。これは、不変の参照カウント文字列にとって「ほとんど些細なこと」です。あるいは、置換(擬似コード)などのアルゴリズムの変更while (s[0]==' ') s = s.substring(1) for(i=0; i<s.len && s[i]==' '; ++i); s=s.substring(i)---ただし、これには潜在的なパフォーマンスの問題をすでに知っている必要があります(プロファイラーはここで継続的に学習するための貴重なツールです)。
peterchen 2017年

@ThorbjørnRavnAndersen、私はコンサルタントとしてチームがプロジェクトを完了するのを手伝いましたが、(スパゲッティコード以外に)深刻なパフォーマンスの問題が計画されていなかったため、それは不可能でした。それはすべての患者の病歴を時系列で示すことになっていた。Googleマップが全世界を取得するように、データ全体に対して1つのリクエストが行われました。悪いコードを開発し、後でプロファイリングを期待して、プロジェクトを失敗させました。
ペドロアマラルクート

30

プロファイルを作成していない場合は、時期尚早です。


3
私はその背後にある考え方に同意しますが、実装がCPUサイクルに完全に拘束されていない限り、再現可能で一般化できる測定値を取得することは困難です。安定しているほど、現実的ではありません。
peterchen 2009年

1
上記の答えで私が抱えている問題は、コード化する前にアルゴリズムを最適化できないことを意味しているということです。私の作業方法は、機能要件を満たすようにアルゴリズムを設計する傾向があります。コーディングを開始する前に、パフォーマンス要件(たとえば、高度な複雑さや大きなデータセットにヒットする可能性がある)に失敗する可能性があるかどうかを確認し、アルゴリズムを最適化します。最適化は、最適なソリューションに到達するための単なる改良であり、多くの場合、設計段階で最も効率的に行われます。
SmacL 2017年

2
同意しません。クヌースは小さな効率について話していました。多くの場合、最適化は設計段階で行われます。これには、適切なデータ構造とアルゴリズムの選択が含まれます。これらは、パフォーマンスに大きな影響を与えることが多く、後で交換する必要はありません。
haslersn 2017年

@haslersn:「Knuthは小さな効率について話していました」Donald Knuth:「今日のソフトウェアエンジニアの多くが共有する一般通念は、小さな効率を無視することを求めています。しかし、これは単に虐待に対する過剰反応だと思います(...)確立されたエンジニアリング分野12%の改善は、簡単に得られ、限界とは見なされません(...)」
Pedro AmaralCouto19年

27

私の質問は、特定の手法が異なっていても、特にあいまいまたは難読化されていない場合、それは本当に時期尚早の最適化と見なすことができるかということです。

ええと...つまり、コストが同じ(使用、読み取り、変更の同じ労力)の2つのテクニックが手元にあり、1つはより効率的です。いいえ、より効率的なものを使用することは、その場合、時期尚早ではありません。

コードの記述を中断して、一般的なプログラミング構造/ライブラリルーチンの代替案を探す機会がありますが、記述しているものの相対速度が実際には重要ではないことはわかっていても、どこかに効率的なバージョンがぶら下がっています。 ..それは時期尚早です。


3
同意します。ユースケースに対して1つのアルゴリズムがより効率的であることがわかっている場合は、必ずより効率的なアルゴリズムを使用してください。最も効率的なアルゴリズムがわからない場合は、使用しているものを使用し、後でプロファイルを作成して、問題があるかどうかを確認してください。
grepsedawk 2008

10

これが、時期尚早の最適化を回避するという概念全体で私が目にする問題です。

それを言うこととそれをすることの間には断絶があります。

私は多くのパフォーマンスチューニングを行い、他の点では適切に設計されたコードから大きな要素を絞り出しましたが、時期尚早の最適化なしで行われたようです。 これが例です。

ほとんどすべての場合、パフォーマンスが最適ではない理由は、私がギャロッピングの一般性と呼んでいるものです。これは、抽象的な多層クラスと完全なオブジェクト指向設計の使用であり、単純な概念はあまりエレガントではありませんが、完全に十分です。

そして、通知駆動型アーキテクチャや、オブジェクトのブールプロパティを設定するだけでアクティビティの無制限の波及効果が得られる情報隠蔽など、これらの抽象的なデザインコンセプトが教えられている教材では、どのような理由がありますか?効率

それで、それは時期尚早の最適化でしたか?


この答えは、抽象化と一般化に関する主要な問題の1つを示しているため、気に入っています。幅広いユースケースをサポートするようにクラス階層を一般化すると、最も一般的なユースケースのパフォーマンスを著しく損なうことは非常に簡単です。また、機能が意図された使用の規模に対して許容可能なレベルのパフォーマンスで提供されているかどうかを確認せずに、特定の機能を提供するクラスにラッチすることも簡単です。
SmacL 2010

1
「単純な概念はエレガントではないが完全に十分である場合」単純なコードが要件を満たしている場合、複雑なコードが単純なコードよりエレガントになることはめったにありません。(ただし、誰かがより複雑なケースで実行しようとした場合、サポートされていない状態/入力を明確に示して、単純なコードが実際に爆発することを確認する必要があると主張します。)
jpmc26 2017年

8

まず、コードを機能させます。次に、コードが正しいことを確認します。第三に、それを速くします。

ステージ#3の前に行われるコード変更は、間違いなく時期尚早です。それ以前に行われた設計の選択をどのように分類するか(適切なデータ構造を使用するなど)は完全にはわかりませんが、パフォーマンスが優れている人よりも、プログラミングが簡単な抽象化を使用することを好みます。プロファイリングを使い始め、結果を比較するための正しい(ただし頻繁に遅い)リファレンス実装を持つことができる段階。


7

あなたが話しているように見えるのは、ハッシュベースのルックアップコンテナを使用するような最適化と、多くのキールックアップが行われる場合の配列のようなインデックス付きコンテナを使用することです。これは時期尚早の最適化ではありませんが、設計段階で決定する必要があります。

Knuthルールの最適化の種類は、最も一般的なコードパスの長さを最小化し、アセンブリでの書き換えやコードの単純化などによって最も実行されるコードを最適化して、一般性を低くすることです。しかし、これを行うことは、コードのどの部分がこの種の最適化を必要とするかを確認するまでは役に立ちません。最適化すると、コードの理解や維持が難しくなります。したがって、「時期尚早の最適化はすべての悪の根源です」。

クヌースはまた、プログラムが使用するアルゴリズムを最適化するのではなく、問題へのアプローチを変更する方が常に良いと述べています。たとえば、少し調整すると最適化によって速度が10%向上する可能性がありますが、プログラムの動作方法を根本的に変更すると、10倍高速になる可能性があります。

この質問に投稿された他の多くのコメントへの反応:アルゴリズムの選択!=最適化


7

データベースの観点からは、設計段階で最適な設計を考慮しないことは、せいぜいばかげたことです。データベースは簡単にリファクタリングされません。それらが不十分に設計されると(これは、最適化を考慮しない設計は、時期尚早の最適化のナンセンスの背後に隠れようとしても、それから回復することはほとんどできません)、データベースが基本的すぎて、システム全体の操作。アプリケーション全体でカーソルを使用したために100万人のユーザーがいて、人々が叫んでいるまで待つよりも、予想される状況に最適なコードを考慮して正しく設計する方がはるかにコストがかかりません。sargeableコードの使用、可能な限り最良のインデックスと思われるものの選択などの他の最適化は、設計時にのみ意味があります。速くて汚いというのには理由があります。これまでうまく機能することはできないので、優れたコードの代わりに迅速性を使用しないでください。また、率直に言って、データベースのパフォーマンスチューニングを理解すると、パフォーマンスが良くないコードを書くよりも、同時にまたはパフォーマンスが良くなる可能性が高いコードを書くことができます。データベース設計のパフォーマンスが優れていることを学ぶために時間を割かないことは、開発者の怠惰であり、ベストプラクティスではありません。


6

格言のポイントは、通常、最適化は複雑で複雑であるということです。そして通常、アーキテクト/デザイナー/プログラマー/メンテナーは、何が起こっているのかを理解するために、明確で簡潔なコードを必要とします。

特定の最適化が明確で簡潔な場合は、自由に試してみてください(ただし、戻って、その最適化が効果的かどうかを確認してください)。重要なのは、パフォーマンスのメリットが最適化の作成と維持にかかるコストを上回るまで、開発プロセス全体を通じてコードを明確かつ簡潔に保つことです。


2
実際、かなりの「最適化」は、ジョブに適切なアルゴリズムを選択することになります。これは高レベルの活動であり、高レベルの結果が得られます。これは、クヌースの引用の「小さな効率」とはかけ離れています。
Shog9 2008

4

パフォーマンスの問題が確認された場合にのみ最適化を試みます。

時期尚早の最適化の私の定義は、「パフォーマンスの問題であることが知られていないコードに無駄な労力」です。最適化には間違いなく時間と場所があります。ただし、コツは、アプリケーションのパフォーマンスに影響を与える場合、および追加コストがパフォーマンスヒットを上回る場合にのみ、追加コストを費やすことです。

コード(またはDBクエリ)を作成するときは、「効率的な」コード(つまり、目的の機能を、合理的な最も単純なロジックで迅速かつ完全に実行するコード)を作成するように努めます。「効率的な」コードは必ずしも「最適化された」コードと同じではないことに注意してください。コード。最適化により、コードがさらに複雑になり、そのコードの開発コストと保守コストの両方が増加することがよくあります。

私のアドバイス:利益を定量化できる場合にのみ、最適化のコストを支払うようにしてください。


4

プログラミング時には、いくつかのパラメータが不可欠です。これらの中には:

  • 読みやすさ
  • 保守性
  • 複雑
  • 堅牢性
  • 正しさ
  • パフォーマンス
  • 開発時間

最適化(パフォーマンスを重視する)は、他のパラメーターを犠牲にすることが多く、これらの領域の「損失」とバランスを取る必要があります。

うまく機能するよく知られたアルゴリズムを選択するオプションがある場合、事前に「最適化」するコストは許容できることがよくあります。


1
上記のリストで最も重要なQAパラメータが1つ欠けています。要件を満たす。ソフトウェアの一部が対象読者の要件を満たしていない場合、他のすべてのパラメーターは無意味です。パフォーマンスが許容できない場合、要件は満たされていません。
SmacL 2008

3
それは正しさでカバーされていると言えます。その上、「できるだけ速く」という意味での「パフォーマンス」が要件の中にあることはめったになく、他のニーズとのトレードオフであるというオラのポイントでさえ真実のままです。
frankodwyer 2008

4

最適化は、非常に高いレベルから非常に低いレベルまで、さまざまなレベルの粒度で発生する可能性があります。

  1. 優れたアーキテクチャ、疎結合、モジュール性などから始めます。

  2. 問題に適したデータ構造とアルゴリズムを選択してください。

  3. より多くのコード/データをキャッシュに収めようとして、メモリを最適化します。メモリサブシステムはCPUよりも10〜100倍遅く、データがディスクにページングされると、1000〜10,000倍遅くなります。メモリ消費に注意することは、個々の命令を最適化するよりも大きな利益をもたらす可能性が高くなります。

  4. 各関数内で、フロー制御ステートメントを適切に使用します。(不変の式をループ本体の外に移動します。最も一般的な値を最初にスイッチ/ケースなどに入れます。)

  5. 各ステートメント内で、正しい結果が得られる最も効率的な式を使用してください。(乗算とシフトなど)

除算式とシフト式のどちらを使用するかを慎重に選択することは、必ずしも時期尚早の最適化ではありません。最初にアーキテクチャ、データ構造、アルゴリズム、メモリフットプリント、およびフロー制御を最適化せずにこれを行う場合は、時期尚早です。

そしてもちろん、目標パフォーマンスのしきい値を定義しないと最適化は時期尚早です。

ほとんどの場合、次のいずれかです。

A)高レベルの最適化を実行することで目標のパフォーマンスしきい値に到達できるため、式をいじる必要はありません。

または

B)考えられるすべての最適化を実行した後でも、目標のパフォーマンスしきい値を満たせず、低レベルの最適化では、読みやすさの喪失を正当化するのに十分なパフォーマンスの違いが生じません。

私の経験では、ほとんどの最適化問題は、アーキテクチャ/設計またはデータ構造/アルゴリズムレベルのいずれかで解決できます。メモリフットプリントの最適化がしばしば(常にではありませんが)求められます。ただし、フロー制御と式のロジックを最適化する必要はめったにありません。そして、それが実際に必要な場合、それが十分であることはめったにありません。


3

極端な場合には、プロファイラーを使用する必要があります。プロジェクトのエンジニアは、パフォーマンスのボトルネックがどこにあるかを知っておく必要があります。

「時期尚早の最適化」は非常に主観的だと思います。

コードを書いていて、ハッシュテーブルを使用する必要があることがわかっている場合は、それを実行します。私はそれを何らかの欠陥のある方法で実装せず、誰かが問題を抱えているときにバグレポートが1か月または1年後に到着するのを待ちます。

再設計は、最初から明白な方法で設計を最適化するよりもコストがかかります。

明らかに、最初はいくつかの小さなことが見逃されますが、これらが重要な設計上の決定になることはめったにありません。

したがって、設計を最適化しないことは、IMO自体がコードの臭いです。


ボトルネックは、問題になるとは思わなかったコードのセクションで発生することがよくあります。プロファイリングは、見せかけを省き、プログラムの実際のコストセンターを示します。最初から明白なことを行うのが最善ですが、それ以外のすべてについてはプロファイリングがあります。
クリススミス

2

ノーマンの答えは素晴らしいです。どういうわけか、あなたは日常的にいくつかの「時期尚早の最適化」を行いますが、それ以外の方法では完全に非効率的であることが知られているため、実際にはベストプラクティスです。

たとえば、ノーマンのリストに追加するには:

  • String + String(ループ内)の代わりにJava(またはC#など)でStringBuilder連結を使用する。
  • 次のようにCでループするのを避けますfor (i = 0; i < strlen(str); i++)(ここでstrlenは、各ループで呼び出される、毎回文字列をウォークする関数呼び出しであるため)。
  • ほとんどのJavaScript実装ではそうですが、実行する方が高速for (i = 0 l = str.length; i < l; i++)であり、それでも読み取り可能であるため、OKです。

等々。しかし、そのようなマイクロ最適化は、コードの可読性を犠牲にして行われるべきではありません。


2

Knuthの最初の引用は、gotoホットスポットを排除する方法として慎重に選択および測定された領域での使用を促進するために彼が書いた論文からのものであったことは注目に値します。彼の引用は、gotoこれらの重要なループを高速化するために使用する理由を正当化するために彼が追加した警告でした。

[...]繰り返しになりますが、たとえば、nの平均値が約20であり、プログラムで検索ルーチンが約100万回実行された場合、これは全体の実行速度の顕著な節約になります。[を使用したgotos]このようなループ最適化は、習得するのが難しくなく、私が言ったように、プログラムのごく一部で適切ですが、多くの場合、大幅な節約になります。[...]

そして続けます:

今日のソフトウェアエンジニアの多くが共有している一般通念は、小規模での効率を無視することを求めています。しかし、これは、「最適化された」プログラムをデバッグまたは維持できないペニーワイズおよびポンドバカなプログラマーによって実践されていると彼らが見ている虐待に対する単なる過剰反応であると私は信じています。確立された工学分野では、簡単に得られる12%の改善は、限界とは見なされません。ソフトウェア工学でも同じ視点が普及するはずだと思います。もちろん、ワンショットの仕事でそのような最適化を行うことはしませんが、質の高いプログラムを準備することが問題になる場合は、そのような効率を否定するツール[つまり、goto このコンテキストでのステートメント]に制限したくありません。

彼が引用符で「最適化」をどのように使用したかを覚えておいてください(ソフトウェアはおそらく実際には効率的ではありません)。また、彼がこれらの「ペニーワイズアンドパウンドバカ」プログラマーを批判しているだけでなく、小さな非効率性を常に無視するように提案して反応する人々にも注意してください。最後に、頻繁に引用される部分に:

効率の目標が悪用につながることは間違いありません。プログラマーは、プログラムの重要でない部分の速度について考えたり心配したりするのに膨大な時間を浪費します。これらの効率化の試みは、デバッグと保守を考慮すると、実際には大きな悪影響を及ぼします。小さな効率、たとえば97%の時間は忘れておく必要があります。時期尚早の最適化はすべての悪の根源です。

...そしてプロファイリングツールの重要性についてもう少し:

測定ツールを使用しているプログラマーの普遍的な経験では、直感的な推測が失敗するため、プログラムのどの部分が本当に重要であるかを事前に判断することはしばしば間違いです。このようなツールを7年間使用した後、これから作成するすべてのコンパイラーは、プログラムのどの部分が最もコストがかかるかを示すフィードバックをすべてのプログラマーに提供するように設計する必要があると確信しました。実際、このフィードバックは、特にオフにされていない限り、自動的に提供される必要があります。

人々は彼の引用をあちこちで誤用しており、彼の論文全体がマイクロ最適化を提唱していたとき、マイクロ最適化は時期尚早であるとしばしば示唆しています!彼が批判していた人々のグループの1つは、この「一般通念」を繰り返し、小さなものの効率を常に無視していると述べ、元々はあらゆる形態のマイクロ最適化を思いとどまらせるようなタイプに対して部分的に向けられた彼の引用を誤用していることがよくあります。 。

それでも、プロファイラーを持っている経験豊富な手が使用した場合、適切に適用されたマイクロ最適化を支持する引用でした。、のような今日の類推相当するものはあるかもしれない「人々は彼らのソフトウェアの最適化をブラインドのスタブを取るべきではありませんが、参照の局所性を向上させるための重要な分野に適用されるときにカスタムメモリアロケータは、大きな違いを生むことができ、」または、 "手書きSIMDコードを使用してSoA担当者は保守が非常に難しく、あらゆる場所で使用するべきではありませんが、経験豊富でガイド付きの手によって適切に適用されると、メモリをはるかに速く消費する可能性があります。

Knuthが上記で宣伝したように、慎重に適用されたマイクロ最適化を宣伝しようとしているときはいつでも、ソフトウェア全体を使用するように書き直すなど、初心者が興奮しすぎて盲目的に最適化を突き刺さないように、免責事項を提出することをお勧めしますgoto。それは部分的に彼がしていたことです。彼の引用は事実上大きな免責事項の一部でした。ちょうどオートバイが燃える火の穴を飛び越えるのと同じように、アマチュアは家でこれを試してはいけないという免責事項を追加すると同時に、適切な知識と設備なしで試して怪我をする人を批判します。

彼が「時期尚早の最適化」と見なしたのは、彼らが何をしているのかを事実上知らなかった人々によって適用された最適化でした。最適化が本当に必要かどうかわからなかった、適切なツールで測定しなかった、多分彼らのコンパイラまたはコンピュータアーキテクチャ、そして何よりも、「ペニーワイズアンドパウンドバカ」でした。つまり、ペニーをつまんで最適化する(数百万ドルを節約する)大きな機会を見落としていました。より効果的にデバッグおよび保守します。

「ペニーワイズアンドパウンドバカ」のカテゴリに当てはまらない場合はgoto、クリティカルループを高速化するためにを使用している場合でも、クヌースの標準によって時期尚早に最適化されていません(ありそうもないことです)。今日のオプティマイザーに対して大いに役立つが、もしそうなら、そして本当に重要な領域では、時期尚早に最適化することはないだろう)。あなたが本当に必要とされている分野であなたがしていることを実際に適用していて、彼らがそれから本当に恩恵を受けているなら、あなたはクヌースの目にはちょうど素晴らしいことをしています。


1

私にとって時期尚早の最適化とは、システムが機能する前に、実際にコードのプロファイルを作成してボトルネックがどこにあるかを知る前に、コードの効率を改善しようとすることを意味します。その後も、多くの場合、読みやすさと保守性は最適化の前に来る必要があります。


1

認識されているベストプラクティスは時期尚早の最適化ではないと思います。それは、使用シナリオに応じて潜在的なパフォーマンスの問題であるwhatifsの書き込み時間に関するものです。良い例:ボトルネックであることが証明される前に、オブジェクトの反射を最適化しようとして1週間燃焼した場合、最適化が時期尚早です。


1

ユーザーまたはビジネスのニーズのために、アプリケーションのパフォーマンスを向上させる必要があることがわかった場合を除いて、最適化について心配する理由はほとんどありません。それでも、コードのプロファイルを作成するまでは何もしないでください。次に、最も時間がかかる部分を攻撃します。


0

私の見方では、さまざまなシナリオでどれだけのパフォーマンスを得ることができるかを知らずに何かを最適化すると、時期尚早の最適化になります。コードの目標は、人間が読みやすくすることです。


0

同様の質問に投稿したように、最適化のルールは次のとおりです。

1)最適化しないでください

2)(専門家のみ)後で最適化する

最適化が時期尚早なのはいつですか?通常。

例外は、おそらく設計、または頻繁に使用される十分にカプセル化されたコードにあります。過去に、コンパイラが生成したアセンブラを調べて、内部ループ内の不要な命令を1つ削除すると、30%のスピードアップが得られる、タイムクリティカルなコード(RSA実装)に取り組んできました。しかし、より洗練されたアルゴリズムを使用することによるスピードアップは、それよりも桁違いに大きかった。

最適化するときに自問するもう1つの質問は、「ここで300ボーモデムの最適化と同等のことをしているのか」です。。言い換えれば、ムーアの法則は、やがてあなたの最適化を無関係にするのでしょうか。スケーリングの多くの問題は、問題にハードウェアを追加するだけで解決できます。

最後になりましたが、プログラムの進行が遅くなる前に最適化するのは時期尚早です。あなたが話しているのがWebアプリケーションの場合、負荷をかけて実行してボトルネックがどこにあるかを確認できますが、他のほとんどのサイトと同じスケーリングの問題が発生し、同じソリューションが適用される可能性があります。

編集:ちなみに、リンクされた記事に関して、私はなされた仮定の多くに疑問を呈します。第一に、ムーアの法則が90年代に機能しなくなったというのは真実ではありません。第二に、ユーザーの時間がプログラマーの時間よりも価値があることは明らかではありません。ほとんどのユーザーは(控えめに言っても)とにかく利用可能なすべてのCPUサイクルを必死に使用しているわけではなく、おそらくネットワークが何かをするのを待っています。さらに、プログラマーの時間が他の何かの実装から、ユーザーが電話をしている間にプログラムが行うことを数ミリ秒短縮することに転用される場合、機会費用が発生します。それより長いものは通常最適化ではなく、バグ修正です。

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