なぜ時期尚早な最適化が諸悪の根源なのか

なぜ時期尚早な最適化が諸悪の根源なのでしょうか?

起源

Donald Knuth はコンピュータ サイエンスの著名な学者であり、コンピュータ プログラミングの先駆者の 1 人です。彼はコンピュータ サイエンスの「バイブル」として知られ、「コンピュータ プログラミング アート」の著者でもあります。彼は、アルゴリズムの時間計算量と空間計算量を記述するために有名な「ビッグ オー 記法」を提案し、科学的および科学的な文字を植字するための TeX システムを開発しました。彼は、チューリング賞、フォン・ノイマン賞、国家科学勲章など、多くの栄誉を獲得しています。今日話したいのは、彼が提唱したソフトウェア設計の重要な原則です「時期尚早な最適化は諸悪の根源です。時期尚早な最適化は諸悪の根源です。」

時期尚早な最適化が諸悪の根源

「時期尚早な最適化が諸悪の根源」と言われるのはなぜですか?

コードの最適化が早すぎると、間違った目標に囚われ、最も重要な目標を見失ってしまう可能性があると思います。非常に単純な例を挙げると、ユーザーを獲得する製品を迅速に構築する必要があります。現時点で最も重要な目標は、この製品をオンラインで迅速に入手することであり、この製品を使いやすくすることではありません (中国のインターネットの下では、そのような製品が無数にあります)後者のエクスペリエンスとパフォーマンス問題のみに注意を払い、速度を無視する場合、現在の競争の激しい市場ではまったく勝ち目はありません。

もちろん、上記の例は知覚レベルのものであり、多くのプログラマーにとって、製品レベルの内容には関与しない可能性があります。ソフトウェア設計の観点から見ると、合理的に言えば、時期尚早な最適化は次の問題を引き起こす可能性があります。

1. コードの複雑さの増加: 過剰な最適化はコードの複雑さの増加につながる可能性があり、コードの可読性と保守性が低下します。コードが複雑すぎると、開発者がコードを理解して保守することが難しくなり、開発コストと時間が増加する可能性があります。
2. 開発時間とリソースの消費: 過剰な最適化により、開発者は他の重要な開発タスクを無視して、コードのパフォーマンスの最適化に多くの時間とリソースを費やす可能性があります。これにより、プロジェクトのスケジュールが遅れ、開発コストが増加する可能性があります。
3. コードの移植性の低下: 過剰な最適化は、コードの移植性の低下につながる可能性があります。コードが特定のハードウェアまたはオペレーティング システムに依存しすぎると、コードが他の環境で実行できなくなる可能性があります。
4. コードのスケーラビリティを低下させる: 過剰な最適化により、コードのスケーラビリティが低下する可能性があります。コードが特定のアルゴリズムまたはデータ構造に依存しすぎると、コードが将来の要件の変更に適応できなくなる可能性があります。

時期尚早な最適化の典型的なケース

ソフトウェア工学の歴史の中では、ソフトウェアの性能を重視しすぎてプロジェクトが失敗するケースは数多くありますが、例えば以下で説明するプロジェクトのいくつかは、ソフトウェア工学の歴史の中で非常に有名なプロジェクトです(もちろん、新世代のプログラマーの中には、もうそのことを知らない人もいるかもしれません。)。

1. IBM OS/360 オペレーティング システム: 1960 年代に、IBM Corporation は OS/360 オペレーティング システムを開発しました。これは、当時最大のソフトウェア エンジニアリング プロジェクトの 1 つでした。開発プロセス中、IBM はコードのパフォーマンスに過度に注意を払いすぎたため、コードの複雑さが増し、開発時間の遅れが生じ、最終的にはプロジェクトが失敗しました。このプロジェクトは、最近読んでいた古典的なソフトウェア エンジニアリングの本「The Mythical Man-Month」にまだ載っていることを知っています。あなたにも読むことをお勧めします。このプロジェクトは最終的には失敗しましたが、全体に貴重な経験も残しました。ソフトウェアエンジニアリング分野です。
2. Netscape Navigator ブラウザ: 1990 年代に、Netscape Corporation は、当時最も人気のあるブラウザの 1 つである Navigator ブラウザを開発しました。開発プロセス中、Netscape はコードのパフォーマンスに過度に注意を払ったため、コードの複雑さが増し、開発時間の遅れが生じ、最終的にはブラウザの市場シェアが大幅に低下しました。
3. Windows Vista オペレーティング システム: 2000 年代初頭に、Microsoft Corporation は Windows Vista オペレーティング システムを開発しました。これは、当時最大のソフトウェア エンジニアリング プロジェクトの 1 つでした。開発プロセス中、Microsoft はコードのパフォーマンスに過度に注意を払った結果、コードの複雑さが増大し、開発時間が遅延し、最終的にはオペレーティング システムのユーザー エクスペリエンスが低下し、市場の反応が低下しました。ちなみに、私は以前このOSを使用したことがありますが、ユーザーインターフェイスは依然として非常に美しく、多くのUIデザインはWindow7でも使用されています。

時期尚早な最適化を特定する方法

ソフトウェア開発プロセスにおいて、時期尚早な最適化かどうかをどのように判断するのでしょうか? 一般的な判断基準をいくつか示します。以下を参照してください。

1. パフォーマンス上の問題があるかどうか:コードにパフォーマンス上の問題がない場合、時期尚早に最適化する必要はありません。したがって、最適化する前に、コードのパフォーマンスをテストして、パフォーマンス上の問題があるかどうかを判断する必要があります。
2. 将来発生する可能性のある問題が最適化されているかどうか: 現在の問題ではなく、将来発生する可能性のある問題が最適化されている場合、それは時期尚早の最適化である可能性があります。最適化する前に、将来起こり得る問題ではなく、現在の問題を優先する必要があります。
3. コードの可読性と保守性が犠牲にされているかどうか: コードを最適化するとコードの複雑さが増し、コードの可読性と保守性が低下する場合、それは時期尚早の最適化である可能性があります。最適化の前に、コードの読みやすさ、保守性、スケーラビリティを優先する必要があります。
4. 多くの開発時間とリソースが無駄になっているかどうか: コードの最適化により、コードのパフォーマンスと効率が向上する代わりに、多くの開発時間とリソースが無駄になる場合、それは時期尚早の最適化である可能性があります。最適化する前に、最適化のコストと利点を評価して、最適化が価値があるかどうかを判断する必要があります。

時期尚早に最適化するかどうかは、ケースバイケースで評価する必要があります。最適化する前に、コードのパフォーマンスをテストして、パフォーマンス上の問題があるかどうかを判断する必要があります。同時に、過剰な最適化を避けるために、コードの読みやすさ、保守性、スケーラビリティも優先する必要があります。

要約する

長年 IT 分野で働いてきたエンジニアとして、私はソフトウェア開発において時期尚早の最適化が大きな罠であることを深く理解しています。ソフトウェア開発の初期段階では、コードのパフォーマンスに過度に注意を払い、コードの読みやすさ、保守性、拡張性を無視することがあります。このアプローチでは、コードが複雑になり、コードの可読性と保守性が低下し、開発時間とリソースが大量に浪費される可能性があります。

ソフトウェア開発中は、時期尚早な最適化を避け、代わりにコードの可読性、保守性、拡張性を優先する必要があります。パフォーマンスの最適化が必要な場合は、コードに基づいて最適化する必要があり、パフォーマンスのボトルネックを分析し、アルゴリズムとデータ構造を最適化することで、コードのパフォーマンスと効率を向上させることができます。同時に、パフォーマンスの最適化がソフトウェア開発の唯一の目標ではないことも認識し、コードの品質と信頼性を確保するために、コードの可読性、保守性、スケーラビリティにも注意を払う必要があります。

拡大する

コードの最適化には多くの利点がありますが、すべてのコードを最適化する必要があるという意味ではありません。場合によっては、過剰な最適化は逆効果であり、時間がかかり、労力がかかり、不快なものになります。

「現代のコンピューターサイエンスの創始者」ドナルド・クヌースはかつて「時期尚早の最適化が諸悪の根源である」と述べました。その理由は次のとおりです。高速なプログラムを正確に作成するよりも、より高速に正しいプログラムを作成する方がはるかに簡単です。

プロジェクト開発では、改善する必要のないコードの改善に貴重な時間を浪費し、改善によって付加価値を与えないプログラマーが常に存在します。プロジェクトを最適化する場合、何を最適化する必要があるのか​​、どのように最適化する必要があるのか​​、最適化してはいけないものは何なのか? まず、この記事で説明されている 7 つのことを理解する必要があります。

1. 具体的に何を最適化する必要がありますか?

最適化作業を始める段階では、最適化の内容や目的がまだ明確に定義されていないため、誤解に陥りやすいです。最初から、達成したい効果やその他の最適化関連のさまざまな問題について明確に理解しておく必要があります。これらの目標は明確に記述する必要があり (少なくとも技術に精通したプロジェクト マネージャーはそれを理解し、表現できます)、最適化プロセス全体を通じてこれらの目標を堅持する必要があります。

実際のプロジェクト開発では、さまざまな変数が存在することがよくあります。最初に 1 つの側面を最適化することから始めても、後で別の側面を最適化する必要があることが判明する場合があります。この場合、変更について明確にし、目標が変更されたことをチーム全員に理解させる必要があります。

2. 適切な最適化メトリクスを選択する

適切なメトリクスを選択することは最適化の重要な部分であり、これらのメトリクスに対して最適化作業の進捗状況を測定する必要があります。インジケーターが適切に選択されていないか、単に間違っている場合、あなたの努力が無駄になる可能性があります。

たとえ適切な指標があったとしても、ある程度の識別力が必要です。場合によっては、コードの実行に最も時間がかかる部分の実行に最大限の労力を費やすことが現実的な戦略となります。ただし、Unix/Linux カーネルの時間のほとんどは空のループに費やされることにも注意してください。

達成しやすい指標を安易に選んでしまうと、問題の本質的な解決にはならないため、あまり役に立たないことに注意してください。目標に近い、より複雑な指標を選択する必要があります。

3. 最適化は最先端です

これが効果的な最適化の鍵です。プロジェクト内で自分の目標 (パフォーマンス、リソースなど) に反する箇所を見つけて、そこに労力と時間を費やします。

典型的な例を挙げると、Web プロジェクトの速度が比較的遅いため、開発者は最適化の際にデータベースの最適化に最も力を注ぎ、最終的に本当の問題はネットワーク接続の遅さにあることがわかります。

また、簡単に実現できる成果に気を取られないようにしてください。これらの問題は、対処するのは簡単ですが、必要ではない場合や、目標と一致しない場合があります。最適化が簡単だからといって、努力する価値があるとは限りません。

4. 最適化レベルが高いほど良い

一般に、最適化のレベルが高くなるほど、効果も高くなります。この基準によれば、最良の最適化は、より効率的なアルゴリズムを見つけることです。

たとえば、ソフトウェア開発プロジェクトで、パフォーマンスが低い重要なアプリケーションがあったため、開発チームは最適化を開始しましたが、パフォーマンスはあまり改善されず、パフォーマンスの問題の核心は、テーブル内のバブル ソート アルゴリズムにより、数千の項目が増加しました。

それでも、高レベルの最適化は「特効薬」ではありません。すべてをループ ステートメントの外側に移動するなど、いくつかの基本的なテクニックでも、最適化効果を生み出すことができます。多くの場合、多数の低レベルの最適化によって、1 つの高レベルの最適化と同じ効果が得られます。

また、高度な最適化により一部のコード ブロックが削減されるため、以前にこれらのコード ブロックに対して行った最適化は意味がなくなるため、最初から高度な最適化を検討する必要があることにも注意してください。

5. 時期尚早に最適化しないでください

プロジェクトの初期段階で最適化を行うと、コードが読みにくくなったり、パフォーマンスに影響を与えたりする可能性があります。一方、プロジェクトの後半段階では、以前に行った最適化が何の役割も果たしておらず、時間とエネルギーが無駄に浪費されていることがわかるかもしれません。

正しい方法は、プロジェクトの開発と最適化を 2 つの別々のステップとして実行することです。

6. 直感ではなくプロファイリングに頼る

どこを最適化する必要があるかはすでにわかっていると考える傾向がありますが、これはお勧めできません。特に複雑なソフトウェア システムでは、プロファイリング データが最初に来て、直感が最後に来る必要があります。

最適化の効果的な戦略は、最適化への影響に応じて実行している作業をランク付けすることです。作業を開始する前に最も影響のある「障害」を見つけて、後で小さな障害に取り組みます。

7. 最適化は万能薬ではない

最適化の最も重要なルールの 1 つは、同時にすべてを最適化することはできず、2 つの問題さえも最適化することはできないということです。たとえば、速度を最適化するとリソースの使用率が増加する可能性があり、ストレージの使用率を最適化すると他の場所の速度が低下する可能性があります。最適化の目標に沿ったものを検討する必要があります。

おすすめ

転載: blog.csdn.net/heshihu2019/article/details/132611086