早すぎる最適化は本当にすべての悪の根源ですか?


215

私の同僚は今日、と呼ばれるクラスをコミットしましたThreadLocalFormat。これは基本的にJava Formatクラスのインスタンスをスレッドローカルに移動します。これらはスレッドセーフではなく、作成するには「比較的高価」です。簡単なテストを作成し、1秒間に200,000個のインスタンスを作成できると計算し、その数を作成するように彼に尋ねました。彼は優れたプログラマーであり、チームの全員が高度なスキルを持っているため、結果のコードを理解するのに問題はありませんが、実際に必要のない場所を最適化する場合でした。彼は私のリクエストに応じてコードをバックアウトしました。どう思いますか?これは「時期尚早な最適化」のケースですか?それは実際にどれほど悪いですか?


23
時期尚早な最適化と不必要な最適化を区別する必要があると思います。私にとって時期尚早は、「ライフサイクルの初期に早すぎる」ことを示唆していますが、不必要なことは「重要な価値を加えない」ことを示唆しています。IMO、遅延最適化の要件は見掛け倒しの設計を意味します。

110
はい、しかし、悪は多項式であり、多くのルーツがあり、それらのいくつかは複雑です。
dan_waterworth

7
Knuthがこの1974年に書いたことを考慮すべきです。70年代には、遅いプログラムを書くのは今のように簡単ではありませんでした。彼はJavaやPHPではなく、Pascalを念頭に置いて書いています。
セビング

4
いいえ。すべての悪の根源は貪欲です。
Tulainsコルドバ

12
@ceving 70では、遅いプログラムを書くのは今日と同じくらい簡単でした。間違ったアルゴリズムまたは間違ったデータ構造を選択した場合、BAM!至る所で悪いパフォーマンス。他の方法で議論することもできます。今日、それはより多くのツールであり、プログラマーが最も基本的な保存操作で苦しむソフトウェアをまだ書くことは許されるべきです。並列処理はほとんどコモディティになり、私たちはまだ苦しんでいます。パフォーマンスの低下は、言語やツール、CPU、メモリのせいではありません。それは非常に多くのものの微妙なバランスであり、それが早期に最適化することはほぼ不可能である理由です。
アレックス

回答:


322

完全な引用を覚えておくことが重要です。

私たちは小さな効率を忘れてはなりません。約97%の時間です。早すぎる最適化はすべての悪の根源です。しかし、その重要な3%でチャンスを逃してはなりません。

これが意味することは、測定されたパフォーマンスの問題がない場合、パフォーマンスの向上が得られると考えられるため、最適化すべきではないということです。明らかな最適化(タイトループ内で文字列の連結を行わないなど)がありますが、測定が可能になるまで、単純に明確な最適化ではないものは避けてください。

「時期尚早な最適化」の最大の問題は、予期しないバグが発生し、膨大な時間を浪費する可能性があることです。


7
ドナルド・クヌースから来たので、もし彼がそれを裏付ける証拠を持っているなら、私は驚かないでしょう。BTW、Src:Statements、ACM Journal Computing Surveys、第6巻、第4巻、1974年12月に行った構造化プログラミング。p.268。citeseerx.ist.psu.edu/viewdoc/...
mctylr

28
... 優れたプログラマーは、そのような推論によって自己満足に落ち着かず、重要なコードを注意深く見るのが賢明です。ただし、そのコードが特定された後にのみ(完全な引用の残り)
mctylr

21
今日、2万人のユーザーHashSetに、List最適化の代わりにを使用するのは時期尚早な最適化であると伝えました。問題のユースケースは、静的に初期化されたコレクションであり、唯一の目的はルックアップテーブルとして機能することでした。仕事に最適なツールを選択するのと時期尚早な最適化を選択するのに違いがあると言っているのは間違いではないと思います。あなたの投稿はこの哲学を裏付けていると思います:There are obvious optimizations...anything that isn't trivially clear optimization should be avoided until it can be measured.HashSetの最適化は徹底的に測定され、文書化されています。
クラッシュ

9
@crush:はい:Setまた、よりも意味的に正確で情報量Listが多いため、最適化の側面以上のものがあります。
エリックアリク14

7
早めの最適化を、一般的に高速で実行し、スケーリングし、簡単に最適化できるようにアプリケーションアーキテクチャ全体を設計することと混同しないでください。
エリックアリク14

111

マイクロ最適化はコンテキストを除外するため、時期尚早のマイクロ最適化はすべての悪の根本です。彼らはほとんど期待どおりに振る舞いません。

重要な順序でのいくつかの適切な早期最適化は何ですか:

  • アーキテクチャの最適化(アプリケーション構造、コンポーネント化および階層化の方法)
  • データフローの最適化(アプリケーションの内外)

いくつかの中間開発サイクルの最適化:

  • データ構造。パフォーマンスが向上したり、必要に応じてオーバーヘッドが低下したりする新しいデータ構造を導入します。
  • アルゴリズム(quicksort3とheapsortのどちらを決定するのがよいかです;-))

一部の開発サイクルの最適化の終了

  • コードのホットポット(最適化が必要なタイトループ)を見つける
  • コードの計算部分のプロファイリングベースの最適化
  • アプリケーションのコンテキストで行われ、その影響を正しく測定できるため、マイクロ最適化をすぐに行うことができます。

すべての初期最適化が悪であるわけではありません。開発ライフサイクルの間違ったタイミングでマイクロ最適化を行うと、アーキテクチャに悪影響を与えたり、初期生産性に悪影響を与えたり、パフォーマンスに無関係であるか、最後に悪影響を与える可能性があるため、悪意があります異なる環境条件による開発の。

パフォーマンスに関心がある場合(常にそうするべきである場合)、常に大きく考える。パフォーマンスは全体像であり、次のようなものではありません:intまたはlongを使用すべきですか?ボトムアップの代わりにパフォーマンスを使用する場合は、トップダウンを選択してください。


「最適化:最悪の敵」、ジョセフMニューカマー:flounder.com/optimization.htm
ロンルーブル

53

最初の測定を行わない最適化は、ほとんど常に時期尚早です。

これはこの場合にも当てはまり、一般的な場合にも当てはまります。


ここここ!考慮されていない最適化はコードを維持不可能にし、多くの場合パフォーマンスの問題の原因となります。たとえば、パフォーマンスを向上させると思われるため、プログラムをマルチスレッド化しますが、実際のソリューションは実装が複雑すぎる複数のプロセスでした。
ジェームズアンダーソン

文書化されていない限り。
nawfal

はい。完全に同意する。最初に測定する必要があります。エンドツーエンドで何かをテストし、各ステップを測定するまで、ボトルネックがどこにあるかを知る方法はありません。
オリバーワトキンス

測定はうそをつくことができます。ベテランの専門家がトレースを読んでプロファイルを実行して、何も得るものがないと思った壁にぶつかるのを何週間も見ました。次に、コード全体を読み、数時間で全体的な変更をいくつか行って、10倍の改善を得ました。コード全体の設計が不十分だったため、プロファイルにはホットパスがありませんでした。また、プロファイラーが存在するはずのないホットパスを要求するのを見てきました。「測定する」人はホットパスを最適化するでしょうが、ホットパスは他の貧弱なコードの症状であることに気付いているはずです。
ベンジー

42

最適化は、次の場合に「悪」です。

  • わかりにくいコード
  • かなり多くのコード
  • 安全性の低いコード
  • 無駄なプログラマーの時間

あなたの場合、すでにプログラマーの時間が少しかかっているようで、コードはそれほど複雑ではなく(チームの全員が理解できるというあなたのコメントからの推測)、そしてコードはもう少し将来の証拠ですあなたの説明を理解していれば、スレッドセーフです。少し悪のように聞こえます。:)


4
コスト、つまり弾丸ポイントの条件が、提供された償却額よりも大きい場合のみ。多くの場合、複雑さは価値をもたらします。これらの場合、基準を満たすようにカプセル化できます。また、再利用され、より多くの価値を提供し続けます。

1
これらの最初の2つのポイントは私にとって主要なポイントであり、4番目のポイントは時期尚早な最適化を行うことのマイナスの結果です。特に、誰かが標準ライブラリの機能を再実装しているのを見ると、それは赤旗です。同様に、組み込みコマンドが遅すぎることを心配していたため、文字列操作用のカスタムルーチンを実装する人を見たことがあります。
11

8
コードをスレッドセーフにすることは最適化ではありません。
マッテンツ

38

私はこの質問が5年前のものであることに驚いていますが、それでもKnuthが言わなければならないことを2、3文以上投稿した人はいません。有名な引用を取り巻くいくつかの段落は、それを非常によく説明しています。引用されている論文は「Go to Statementsを使用した構造化プログラミング」と呼ばれ、40年近くなりましたが、論争とソフトウェアの動きの両方が存在しなくなり、多くの人々が決して経験したことのないプログラミング言語の例があります聞いたところでは、驚くほど大量の言葉がまだ当てはまります。

これは大きな引用です(pdfの8ページ、オリジナルの268ページから):

例2から例2aへの速度の改善はわずか約12%であり、多くの人はそれが取るに​​足らないものであると発音します。今日のソフトウェアエンジニアの多くが共有している従来の知恵は、小規模の効率を無視することを求めています。しかし、これは単に「最適化された」プログラムをデバッグしたり維持したりできないペニー賢明な愚かなプログラマーによって実践されていると見られる虐待に対する過剰な反応だと思います。確立されたエンジニアリング分野では、簡単に得られる12%の改善は決して限界とは見なされません。そして、ソフトウェアエンジニアリングでも同じ視点が優先されるべきだと思います。もちろん、ワンショットジョブでこのような最適化を行うことはありませんが、質の高いプログラムを準備することが問題になる場合は、そのような効率を否定するツールに制限したくありません。

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

しかし、その重要な3%でチャンスを逃してはなりません。優れたプログラマーは、そのような推論によって自己満足に落ち着くことはありません。重要なコードを注意深く見るのが賢明でしょう。しかし、そのコードが特定された後にのみ。測定ツールを使用してきたプログラマーの普遍的な経験は、直感的な推測が失敗することであったため、プログラムのどの部分が本当に重要であるかについて先験的に判断することはしばしば間違いです。

前のページのもう1つの良い点:

私自身のプログラミングスタイルは、過去10年間で時代のトレンドに応じて変更されました(たとえば、今ではそれほどトリッキーではなく、使用回数も少なくなっています)が、私のスタイルの大きな変化は当然のことですこの内部ループ現象に。現在、重要な内部ループのすべての操作を非常に慎重に見て、一部の操作を排除できるように、プログラムとデータ構造を変更しようとしています(例1から例2への変更)。このアプローチの理由は次のとおりです。a)内側のループが短いため、時間がかかりません。b)ペイオフは本物です。c)それから、プログラムの他の部分の効率を下げる余裕があります。したがって、より読みやすく、より簡単に記述およびデバッグできます。


20

この引用が、明らかに悪いコードや、パフォーマンスは測定されていませんが、コードサイズを大きくしたり、読みやすさを損なうことなく、非常に簡単に高速化できるコードを正当化するために使用されることがよくあります。

一般的に、初期のマイクロ最適化は悪い考えかもしれません。ただし、マクロ最適化(O(N ^ 2)の代わりにO(log N)アルゴリズムを選択することなど)は多くの場合価値があり、O(N ^ 2)アルゴリズムと次に、O(log N)アプローチを支持して完全に破棄します。

言葉は注意かもしれ O(N ^ 2)アルゴリズムは、シンプルで書きやすいであれば、それは遅すぎることが判明した場合、あなたはずっと罪悪感なしに、後でそれを捨てることができます。ただし、両方のアルゴリズムが同様に複雑な場合、または予想されるワークロードが非常に大きいため、より高速なものが必要であることが既にわかっている場合は、早期に最適化することは、長期的に全体のワークロードを削減する適切なエンジニアリング決定です。

したがって、一般的に、適切なアプローチは、コードの記述を開始する前にオプションが何であるかを確認し、状況に最適なアルゴリズムを意識的に選択することだと思います。最も重要なことは、「時期尚早な最適化がすべての悪の根源」というフレーズは無知の言い訳にはなりません。キャリア開発者は、一般的な運用コストの一般的な考え方を持っている必要があります。たとえば、彼らは知っておくべきです

  • 文字列は数字よりも高い
  • 動的言語は静的に型付けされた言語よりもはるかに遅いこと
  • リンクリストに対する配列/ベクトルリストの利点、およびその逆
  • ハッシュテーブルを使用する場合、ソート済みマップを使用する場合、およびヒープを使用する場合
  • (モバイルデバイスで動作する場合)「double」と「int」はデスクトップ上で同様のパフォーマンスを持ちますが(FPの方が高速かもしれません)、「double」はFPUのないローエンドモバイルデバイスでは100倍遅くなります。
  • インターネットを介したデータ転送はHDDアクセスよりも遅く、HDDはRAMよりも大幅に遅く、RAMはL1キャッシュとレジスタよりもはるかに遅く、インターネット操作は無期限にブロックされる可能性があります(いつでも失敗します)。

また、開発者はデータ構造とアルゴリズムのツールボックスに精通している必要があります。これにより、ジョブに適したツールを簡単に使用できます。

十分な知識と個人的なツールボックスを使用すると、ほとんど楽に最適化できます。必要のない最適化に多くの努力を注ぐの悪です(そして、私そのtrapに何度も陥ることを認めています)。しかし、配列の代わりにセット/ハッシュテーブルを選択するか、string []の代わりにdouble []に数値のリストを保存するのと同じくらい簡単に最適化する場合は、なぜですか?ここではKnuthに反対するかもしれませんが、確信はありませんが、高レベルの最適化について話しているのに対して、彼は低レベルの最適化について話していたと思います。

覚えておいてください。その引用は元々1974年のものです。1974年にはコンピューターが遅く、計算能力が高かったため、一部の開発者は行ごとに過剰に最適化する傾向がありました。それがクヌースが押しのけたものだと思います。彼は「パフォーマンスについてまったく心配しないでください」と言っていませんでした。Knuthは最適化の方法を説明ていました。つまり、ボトルネックにのみ焦点を当てる必要があります。その前に、ボトルネックを見つけるための測定を実行する必要があります。

測定するプログラムを作成するまで、ボトルネックを見つけることができないことに注意してください。つまり、測定する何かが存在する前に、パフォーマンスの決定を下す必要あります。誤った判断を下すと、これらの決定を変更するのが難しい場合があります。このため、ハードデータが利用できない場合に合理的な判断を下せるように、物価がいくらになるかを一般的に把握しておくことをお勧めします。

最適化の早さ、パフォーマンスの心配の程度は、仕事によって異なります。数回しか実行しないスクリプトを作成する場合、パフォーマンスを心配することは通常、時間の無駄です。しかし、MicrosoftまたはOracleで働いていて、他の何千人もの開発者が何千もの異なる方法で使用するライブラリに取り組んでいる場合、それを徹底的に最適化するためにお金を払うかもしれません。ユースケースを効率的に。それでも、パフォーマンスの必要性は、読みやすさ、保守性、優雅さ、拡張性などの必要性と常にバランスを取る必要があります。


2
アーメン。仕事のために間違ったツールを使用することを正当化しようとする人々によって、最近、時期尚早な最適化があまりにも寛大に投げかけられています。前もって仕事に適したツールを知っていれば、それを使わない言い訳はありません。
粉砕

13

個人的には、前のスレッドで説明したように、パフォーマンスの問題が発生することがわかっている状況では、初期の最適化が悪いとは思いません。たとえば、私は定期的に数千万のエンティティを扱うサーフェスモデリングおよび分析ソフトウェアを作成します。設計段階での最適なパフォーマンスの計画は、脆弱な設計の後半の最適化よりもはるかに優れています。

考慮すべきもう1つのことは、アプリケーションが将来どのように拡張されるかです。コードの寿命が長いと考える場合、設計段階でパフォーマンスを最適化することもお勧めします。

私の経験では、遅い最適化はわずかな報酬を高い価格で提供します。アルゴリズムの選択と調整による設計段階での最適化は、はるかに優れています。プロファイラーに依存して、コードがどのように機能するかを理解することは、高性能なコードを取得するための優れた方法ではありません。事前に知っておく必要があります。


これは確かに正しいです。時期尚早な最適化は、コードがより複雑になり、不明確な利点のために理解が難しくなり、局所的な影響しか与えられない(デザインが世界的な影響を与える)場合だと思います。
ポール・ド・フリーズ08年

2
定義がすべてです。最適化は、最適な方法で実行するためのコードの設計と作成として行います。ここではほとんどの場合、コードが十分に高速または効率的ではないことが判明すると、コードをハッキングするものとして扱います。通常、設計中に最適化に多くの時間を費やします。

3
最初に設計を最適化し、最後にコードを最適化します。
BCS

あなたの場合は非常に正しいですが、ほとんどのプログラマーはパフォーマンスの問題にぶつかると信じていますが、実際には決して起こりません。多くの場合、データの基本的なテストで1000000エンティティに達するまでパフォーマンスが良好であることが示される場合、1000のエンティティを処理するときのパフォーマンスが心配になります。
トビーアレン

1
「設計段階で最適なパフォーマンスを計画することは、弱い設計の後半の最適化よりもはるかに優れています」と「後期の最適化は、高い価格でわずかな報酬を提供します」と非常に言えます。おそらく、生産されたすべてのシステムの97%には当てはまりませんが、多くの-驚くほど多くの-システムに当てはまります。
オロフForshell

10

実際、時期尚早の非最適化がすべての悪の根源であることが多いことを学びました。

人々がソフトウェアを書くとき、最初は不安定、制限された機能、悪い使いやすさ、悪いパフォーマンスなどの問題を抱えています。通常、これらはすべてソフトウェアが成熟すると修正されます。

パフォーマンスを除くこれらすべて。誰もパフォーマンスに関心がないようです。理由は簡単です。ソフトウェアがクラッシュした場合、誰かがバグを修正し、それで終わりです。機能が欠落している場合、誰かがそれを実装して実行します。設計が悪いため、誰もソフトウェアの設計に触れません。今まで。

ボックスを見てください。地獄のように遅い。速くなりますか?たぶん、しかし数パーセントの範囲でのみ。VMWareやVBox、QEMUなどの仮想化ソフトウェアに匹敵するパフォーマンスは得られません。設計上遅いので!

ソフトウェアの問題が非常に遅いことである場合、それは非常に遅いため、これは多数のパフォーマンスを改善することによってのみ修正することができます。+ 10%は、遅いソフトウェアを高速にしないだけです。通常、後の最適化で10%を超えることはありません。

したがって、ソフトウェアにとってパフォーマンスが重要である場合、「ああ、はい、遅いですが、後で改善できます」と考えるのではなく、最初からそれを設計するときに考慮する必要があります。できないから!

私はそれがあなたの特定のケースに実際には当てはまらないことを知っていますが、それは一般的な質問「早すぎる最適化は本当にすべての悪の根源ですか?」-明確なNO。

機能などの最適化はすべて、慎重に設計し、慎重に実装する必要があります。そして、コストと利益の適切な評価が含まれます。アルゴリズムを最適化して、測定可能なパフォーマンスの向上が得られない場合は、あちこちで数サイクルを節約しないでください。

ほんの一例として、関数をインライン展開することでパフォーマンスを改善し、おそらく数サイクルを節約できますが、同時に実行可能ファイルのサイズを大きくすると、TLBやキャッシュミスが数千サイクル、さらにはページング操作。これにより、パフォーマンスが完全に低下します。これらのことを理解していないと、「最適化」が悪くなることがあります。

愚かな最適化は「時期尚早」な最適化よりも悪ですが、どちらもまだ時期尚早な非最適化よりも優れています。


6

POには2つの問題があります。第1に、より多くの機能を記述したりバグを修正したりするために必要な非本質的な作業に使用される開発時間と、コードが効率的に実行されているという誤ったセキュリティ感覚です。POでは、ボトルネックになることのないコードの最適化が必要になる場合がありますが、そうなるコードには気付きません。「時期尚早」ビットは、適切な測定を使用して問題が特定される前に最適化が行われることを意味します。

基本的に、はい、これは時期尚早な最適化のように聞こえますが、バグを導入しない限り、必ずしもそれを取り消すわけではありません-結局、それは今最適化されています(!)


「より多くの機能を書く」のではなく、「より多くのテストを書く」と言うつもりですか?:)
グレッグヒューギル

1
より多くの機能はより多くのテストを必要とします:)
workmad3 08年

えー、はい!それは私が...意味まさにだ
harriyott

2
コードはさらに複雑になり、一般的には使用されない可能性があります。バックアウト(および同様のもの)により、コードがクリーンに保たれます。
ポール・ド・フリーズ08年

3

Mike Cohnがコードの「金メッキ」と呼んでいるものだと思います。つまり、良いかもしれないが必要ではないものに時間を費やしています。

彼はそれに対して助言した。

PS「ゴールドメッキ」は、機能的には一種の機能です。コードを見ると、不必要な最適化、「将来性のある」クラスなどの形をとります。


2
「金メッキ」は最適化とは異なると思います。通常、最適化とは、最高のパフォーマンスを得ようとすることです。一方、「金メッキ」とは、製品にとって重要ではないが見た目やクールさを感じる「添えもの」(すべての追加機能)を追加することです。
スコットドーマン

3

コードの理解に問題はないため、このケースは例外と見なすことができます。

ただし、一般的に最適化はコードの可読性と理解性を低下させるため、必要な場合にのみ適用する必要があります。簡単な例-いくつかの要素のみをソートする必要があることがわかっている場合は、BubbleSortを使用します。ただし、要素が増加する可能性があり、その量がわからない場合は、QuickSortによる最適化(たとえば)は悪ではなく、必須です。そして、これはプログラムの設計中に考慮する必要があります。


1
同意しないでください。バブルソートを使用しないでください。クイックソートは事実上の標準になり、よく理解されており、すべてのシナリオでバブルソートと同じくらい簡単に実装できます。最小公分母はそれほど低くはありません;)

1
アイテムの本当に小さな番号については、クイックソートのために必要な再帰は、バブルソートは(つまりソートされたリストをquicksorting)クイックソートの最悪のシナリオに迅速であることは言うまでもありません...しかし、まともなバブルソートよりも、それは遅くすることができます
workmad3

ええ、しかし、それは異なるニーズに合ったアルゴリズムを選択する方法の一例です;)

確かに、デフォルトのソートとしてクイックソートがあります。バブルソートがパフォーマンスを改善すると思ったら、これは最適化であり、逆ではありません。クイックソートはよく理解されており、一般的に優れているため、デフォルトとしてクイックソートを選択します。

2
デフォルトのソートの私の考えは、ライブラリが私に与えるもの(qsort()、. sort()、(sort ...)、何でも)です。
デビッドソーンリー

3

早すぎる最適化の問題は、既存のコードをより速く書き換えるときにほとんど発生することがわかりました。そもそも複雑な最適化を記述することがどのように問題になるかはわかりますが、ほとんどの場合、壊れていない(既知の)ものを修正する際に早すぎる最適化がそのい頭を育てているのがわかります。

そして、この最悪の例は、誰かが標準ライブラリの機能を再実装しているのを見たときです。それは重大な赤旗です。同様に、組み込みコマンドが遅すぎることを心配していたため、文字列操作用のカスタムルーチンを実装する人を見たことがあります。

これにより、コードの理解が難しく(悪い)、おそらく役に立たない(悪い)作業に多くの時間を費やすことになります。


3

別の観点から見ると、ほとんどのプログラマー/開発者は成功を計画しておらず、「プロトタイプ」はほとんど常にリリース1.0になります。上品で、セクシーで、非常に機能的なフロントエンド(基本的にUI)がユーザーに広く採用され、熱意をもたらした4つの個別のオリジナル製品を実際に体験しました。これらの各製品では、特に大規模で要求の厳しい顧客が製品を採用し始めるにつれて、パフォーマンスの問題が比較的短時間(1〜2年)で忍び込み始めました。すぐにパフォーマンスが問題リストを支配しましたが、新機能の開発は経営陣の優先リストを支配しました。各リリースで新機能が追加されたため、顧客はいらいらするようになりました。新機能は優れたサウンドでしたが、パフォーマンスの問題のためほとんどアクセスできませんでした。

そのため、「プロトタイプ」ではほとんどまたはまったく関係のない非常に基本的な設計および実装の欠陥が、製品(および企業)の長期的な成功の大きな障害となりました。

お客様のデモは、XML DOM、SQL Express、および多くのクライアント側のキャッシュデータを使用して、ラップトップで見た目とパフォーマンスが優れている場合があります。成功すると、本番システムはおそらく火傷をクラッシュさせます。

1976年には、平方根の計算や大きな配列の並べ替えの最適な方法についてまだ議論しており、Don Knuthの格言は、問題の解決に焦点を当てるのではなく、設計プロセスの初期にそのような低レベルルーチンを最適化することに焦点を当てるという誤りに向けられていましたそして、ローカライズされたコード領域を最適化します。

効率的なコード(C ++、VB、T-SQLなど)を記述しない、またはデータストアを適切に設計しない、またはネットワークアーキテクチャを考慮しないという言い訳として格言を繰り返すと、IMOは単に私たちの仕事の本質を非常に浅く理解しています。レイ


1
ハハ、または3人のユーザーのデモがリリース1.0になり、1,000になったとき。
オロフフォーシェル

1

「時期尚早」の定義に依存すると思います。あなたが書いているときに低レベルの機能を素早く作ることは本質的に悪ではありません。それは引用の誤解だと思います。時々、引用はもっと資格があると思います。しかし、読みやすさに関するm_pGladiatorのコメントをエコーし​​ます。


1

答えは次のとおりです。複雑なデータベースクエリなど、特定の種類の作業では効率が大事であると主張します。他の多くの場合、コンピューターはほとんどの時間をユーザー入力の待機に費やしているため、ほとんどのコードの最適化はせいぜい労力の無駄であり、最悪の場合は逆効果です。

場合によっては、効率またはパフォーマンス(知覚または実際)を設計することができます。たとえば、適切なアルゴリズムを選択するか、ユーザーインターフェイスを設計して、たとえばバックグラウンドで特定の高価な操作が発生するようにします。多くの場合、ホットスポットを決定するためのプロファイリングまたはその他の操作により、10/90のメリットが得られます。

これについて説明できる例の1つは、約560個のテーブルが含まれていた裁判管理システムで行ったデータモデルです。最初は正規化(特定の大手5社のコンサルタントが入力したように「美しく正規化」)し、4つの非正規化データを入れるだけで済みました。

  • 検索画面をサポートするマテリアライズドビュー

  • マテリアライズドビューでは実行できなかった別の検索画面をサポートするための、トリガーで維持されるテーブル。

  • 1つの非正規化されたレポートテーブル(これは、データウェアハウスプロジェクトが缶詰になったときにいくつかのスループットレポートを取る必要があるためにのみ存在しました)

  • システム内の非常に多数の異種イベントの最新のものを検索する必要があったインターフェイスの1つのトリガー維持テーブル。

これは(当時)オーストラリアで最大のJ2EEプロジェクトであり、開発者として100年以上も費やしていました。データベーススキーマには4つの非正規化アイテムがあり、そのうちの1つはまったく属していませんでした。


1

時期尚早の最適化は、すべての悪の根源ではありません、それは確かです。ただし、欠点もあります。

  • 開発中により多くの時間を投資する
  • テストにもっと時間をかける
  • そうでなければそこにはないバグを修正するためにより多くの時間を投資する

時期尚早の最適化の代わりに、早期の可視性テストを実行して、最適化の改善が実際に必要かどうかを確認できます。


1

「PMO」(部分引用、つまり)に固執する人のほとんどは、最適化は測定に基づいている必要があり、測定は最後まで実行できないと言います。

また、大規模システム開発の私の経験では、開発が完了に近づいているため、パフォーマンステストが最後に行われます。

これらの人々の「アドバイス」に従えば、すべてのシステムは非常に遅くなります。ハードウェアのニーズが当初想定されていたよりもはるかに大きいため、同様に高価になります。

開発プロセスで定期的にパフォーマンステストを実施することを長年提唱してきました。これは、新しいコードの存在(以前は存在しなかった)と既存のコードの状態の両方を示します。

  • 新しく実装されたコードのパフォーマンスは、既存の同様のコードのパフォーマンスと比較できます。新しいコードのパフォーマンスに対する「感触」は、時間の経過とともに確立されます。
  • 既存のコードが突然混乱に陥った場合、何かが起こったことを理解し、システム全体に影響を与える(後)ではなく、すぐに調査できます。

別のペットのアイデアは、機能ブロックレベルでソフトウェアをインストルメントすることです。システムが実行されると、機能ブロックの実行時間に関する情報が収集されます。システムのアップグレードが実行されると、以前のリリースで実行された機能ブロックと機能が低下した機能ブロックを判別できます。ソフトウェアの画面で、ヘルプメニューからパフォーマンスデータにアクセスできます。

PMOが何を意味するのか、何を意味しないのかについて、この優れた記事をご覧ください。

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