5

私は自分が書いているアプリケーションに苦労してきましたが、私の問題は時期尚早の最適化にあることに気づき始めていると思います。私の完璧主義者の側は、最初からすべてを最適かつ完璧にしたいと考えていますが、これが設計をかなり複雑にしていることがわかりました. 1 つの単純なことをうまく実行する小さくてテスト可能な関数を作成する代わりに、より効率的にするために、できるだけ多くの機能を詰め込むことに傾倒しています。

たとえば、コードがより複雑になるという代償を払って、同じ情報のためにデータベースに何度もアクセスすることを避けています。私の一部は、冗長なデータベース呼び出しについて心配したくないだけです。正しいコードを書くのが簡単になり、フェッチされるデータの量はとにかく少なくなります。私の他の部分は、これを行うと非常に汚くて汚れていると感じます. :-)

私は、データベースに複数回アクセスすることに傾倒しています。これは、ここでの正しい動きだと思います。プロジェクトを完了することがより重要であり、このような最適化のためにハングアップしているように感じます. 私の質問は、時期尚早の最適化を回避するときに使用する正しい戦略ですか?

4

3 に答える 3

20

これは一般的に正しい戦略です。自動化されたテストで徹底的にカバーされた、コードを機能させる。

次に、プログラムがプロファイラーの制御下にある間に自動テストを実行して、プログラムが時間やメモリを消費している場所を見つけることができます。これにより、最適化する場所が示されます。

また、すべてを組み合わせたときに機能するかどうかのコードではなく、機能するコード最適化する方法を示します。

最適に失敗するコードは必要ありません。


私が覚えていなかった引用は、Mich Ravera からのものです。

うまくいかない場合は、どれだけ速くうまくいかなくても構いません。

于 2010-06-09T01:52:36.283 に答える
5

約 97% の確率で、わずかな効率性を忘れる必要があります。時期尚早の最適化は諸悪の根源です。-- ほあれ

@John Saunders はそれを成功させましたが、TDD を適用するだけでは懸念事項を完全に解決できない可能性があります。私は TDD を順守しています。TDD を正しく実行し、リファクタリングを効果的に適用できれば、通常はより無駄のないコードになり、それが機能することがわかっているというメリットがあります。そこに引数はありません。

しかし、あまりにも多くの開発者がパフォーマンスに無頓着なコードを書いているのを目にします。単体テストを書いても、これは防げません。単体テストを書く人はおそらく優れたコーダーであり、優れたコーダーは悪いコードを頻繁に書く傾向がありません。

テストを作成、利害関係者が特定したシナリオの一連のテストにパフォーマンス テストを含めますたとえば、特定のベンダーの 100 の割引製品を取得し、在庫レベルを含めて 3 秒以内に Xml としてフォーマットします

「時期尚早の最適化」は「パフォーマンスに関する懸念」と同じであるという誤りは、ソフトウェア開発の指針となるべきではありません。-- ランドール・ハイド

パフォーマンスの問題を放置するのが遅すぎると、変更が難しすぎたり、コストがかかりすぎたりすることがあります。

一部の記事

于 2010-06-09T05:25:54.623 に答える
1

私にとってのクヌースの引用の重要な側面は、「ペニーワイズでパウンドバカ」です。それが彼が最終的に時期尚早なオプティマイザーを説明した方法です.1ポンド節約する必要があるときにペニーを節約することについて議論し、「最適化された」ソフトウェアを維持するのに苦労している人.

多くの人がクヌースの論文のほんの一部しか引用していないことがよくあります。彼の論文は、ソフトウェアの重要な実行パスgotoを高速化するために使用することを主張していたことを理解する価値があります。

より完全な引用:

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

今日のソフトウェア エンジニアの多くが共有している従来の通念は、小さなことの効率性を無視することを求めています。しかし、これは、「最適化された」プログラムをデバッグしたり維持したりすることができない、小銭のない愚かなプログラマーによって実行されているのを彼らが見ている乱用に対する単純な過剰反応であると私は信じています。確立されたエンジニアリング分野では、12% の改善は簡単に達成できますが、限界とは見なされません。そして私は、ソフトウェア工学においても同じ視点が普及するべきだと信じています。もちろん、単発の仕事でわざわざそのような最適化を行うつもりはありませんが、質の高いプログラムを準備するという問題の場合、そのような効率を否定するツールに自分自身を制限したくありません。

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

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

プログラマーが自分のルーチンのどの部分が本当に重要かを理解したら、ループを 2 倍にするなどの変換を行う価値がありますこの変換によってgo toステートメントが導入されることに注意してください。他のいくつかのループの最適化も同様です。

つまり、これは実際にマイクロレベルでのパフォーマンスに深く関心を持っていた人から来ており、当時 (オプティマイザーは今でははるかに優れています)、速度gotoのために を利用していました。

この Knuth による「時期尚早のオプティマイザ」の確立の核心は、次のとおりです。

  1. 過去の経験や測定値のない、直感/迷信/人間の直感に基づく最適化 (実際に何をしているのかを知らずにやみくもに最適化する)。
  2. ポンドよりもペニーを節約する方法での最適化 (効果のない最適化)。
  3. すべての効率の絶対的な究極のピークを求めています。
  4. 非クリティカル パスで効率を追求する。
  5. コードをほとんど維持/デバッグできないときに最適化しようとしています。

これは最適化のタイミングとは関係ありませんが、クリティカル パスの理解から実際にパフォーマンスを提供するものを理解するまでの経験と理解が必要です。

テスト駆動開発やインターフェース設計への主な焦点などは、Knuth の論文では取り上げられていませんでした。これらは、より現代的な概念とアイデアです。彼は主に実装に集中していました。

とはいえ、これは Knuth のアドバイスに対する良いアップデートです。最初にテストを通じて正確さを確立し、すべてを壊すことなく最適化する余地を残したインターフェース設計を目指してください。

クヌースの現代的な解釈を適用しようとすると、そこに「船」を追加します。ソフトウェアの真のクリティカル パスを測定されたゲインで最適化したとしても、世界で最も高速なソフトウェアが出荷されなければ意味がありません。それを念頭に置いておくと、より賢明な妥協をするのに役立ちます。

私は、データベースに複数回アクセスすることに傾倒しています。これは、ここでの正しい動きだと思います。プロジェクトを完了することがより重要であり、このような最適化のためにハングアップしているように感じます. 私の質問は、時期尚早の最適化を回避するときに使用する正しい戦略ですか?

あなた自身の要件を最もよく理解しているため、上記のいくつかの点を考慮して、最善の判断を下すのはあなた次第です。

私が提案する重要な要素は、これが重い負荷を処理するパフォーマンス クリティカルなパスである場合、最適化の余地を十分に残す方法でパブリック インターフェイスを設計することです。

たとえば、Particleインターフェイスへのクライアントの依存関係を持つパーティクル システムを設計しないでください。カプセル化された状態と単一のパーティクルの実装しかない場合、最適化する余地はありません。その場合、最適化するためにコードベースにカスケード変更を加える必要があるかもしれません。レースカーは、道路が10メートルしかない場合、そのスピードを活かすことができません。代わりに、100 万個の粒子を集約するインターフェイスに向けて設計しParticleSystemます。たとえば、可能な場合は粒子をまとめて処理する高レベルの操作を使用します。これにより、最適化が必要であることがわかった場合に、設計を壊すことなく最適化する余地が十分に残されます。

私の完璧主義者の側は、最初からすべてを最適かつ完璧にしたいと考えていますが、これが設計をかなり複雑にしていることがわかりました.

今、この部分は少し時期尚早に聞こえます。一般に、最初のパスはシンプルにする必要があります。シンプルさは、冗長な作業を行っている場合でも、思ったよりもかなり高速で、多くの場合、手に負えません。

いずれにせよ、これらの点が少なくとも考慮すべき事項を追加するのに役立つことを願っています.

于 2016-01-07T00:07:14.277 に答える