14

パフォーマンスを念頭に置いて、ソフトウェアのコンポーネントまたはアーキテクチャの設計に集中することをお勧めしますか? 私が言いたいのは、パフォーマンス集約型の環境で設計/アーキテクチャをどの程度準備する必要があるかということです。

コンポーネントを設計するときは、適切なオブジェクト指向の原則に従い、コンポーネントが「拡張可能」であることを確認する必要があります。このようにして、パフォーマンスの問題が発生したときに、設計をあちこちで少し調整します。この方法では、ソフトウェアを少し調整しても役に立たないパフォーマンスの問題に遭遇することがよくありました。

あるいは、複雑ではありますが、パフォーマンスの問題を簡単に解決できる設計を考え出す必要があります。ソフトウェアを微調整する必要がありますが、設計はパフォーマンス指向であるため、微調整は非常に簡単です。

注: 上記のいずれの場合でも、パフォーマンスの問題が発生する前にソフトウェアのパフォーマンスを調整しようとしているわけではありません。質問を言い換えると、ソフトウェアの設計はパフォーマンス指向である必要がありますか?

ソフトウェアが実行されると予想される環境にすべて依存すると言って、私に答えないでください。その理由は、産業グレードのソフトウェアのクライアントが、常にますます多くのソフトウェアを必要としているように見えるからです。パフォーマンスが重視される環境でソフトウェアを常に実行することを計画していないかもしれませんが、そうしなければならない場合はどうすればよいでしょうか? それを感じたら、ソフトウェアを再設計する必要がありますか?

この質問は 1 週間前から私を悩ませてきましたが、まだ答えがありません。これについてどう思いますか?

4

10 に答える 10

27

私がこれを書いているとき、すでに 2 人の人が早すぎる最適化に関する Knuth の引用を返信しています。それはやや誤解を招くと思います。その背後にある考え方と、このトピックに関する多くのアドバイスの背後にあるのは、プログラムはアルゴリズムの集まりであり、十分に効率的でない場合は、どのアルゴリズムが遅すぎるかを判断し、それを何かに置き換えることができるということです。より良い。

この種のことは、プログラムの相互接続性を無視します。アルゴリズムはすべて、一部の API の背後に隠されています。「ビジョン」は、API の背後にあるアルゴリズムが不透明であり、別のアルゴリズムと交換可能であるということですが、API によって呼び出し元に課せられた制約は無視されます。私はかなりの割合でネットワーク プログラミングを行ってきましたが、効率的に動作しない API を設計することで、効率の悪いソフトウェアを簡単に作成することができます。(ネットワーク プログラミングでは、たとえば、呼び出し元が完全なメッセージをメモリ内に構築する必要がある API は、データのストリーミングを可能にする API よりも設計と実装が容易です。)

したがって、単純化された簡潔な引用に惑わされないでください。小さなことを気にするべきではありません (特に、70 年代の人々が行ったことについてはまったく心配する必要はありません。コンパイラーは今でははるかにスマートになっています)。ただし、パフォーマンスの問題は完全に無視して、「いつでもプロファイリングして後で改善することができます。必要な場合」は、大幅な再実装を行わなければならない行き止まりにつながる可能性があります。

ああ、「拡張性を考慮した設計」に反対することもお勧めします。機能する最も単純なことを行い、後で自分が持っているものを一般化すると物事がより簡単または単純になることがわかった場合は、それを実行してください。私の経験では、不必要に一般的な設計を行うと、コンポーネントが一般的なケースでどのようなことを行うべきかを初期設計で実際に予測できなかったため、実際にはあまり拡張できない使いにくいコンポーネントが作成されるだけです。そしてどうやって。

于 2009-10-10T14:25:20.347 に答える
6

プロジェクトの設計では、拡張性、保守性、パフォーマンス、出荷までの時間などのバランスを取る必要があります。

拡張性のためにパッケージと高レベルのダイアグラムを設計してから、パフォーマンスのために低レベルのダイアグラムを設計しようとします。

于 2009-10-10T14:04:35.317 に答える
3

私は心を込めてjkの答えを2番目にしなければなりません。

Knuthの引用は、建築を伴わない問題の小さな領域の外では、実際の生活にはいくぶん当てはまりません

例として、元の設計ではデータの100%がデータベースから1つのチャンクにロードされると想定されていたため、最近、かなり複雑なシステムを最初から再構築するために3〜4か月を費やす必要がありました。これは、データセットが元の設計者の予想の約100倍に成長し、システムが2Gの使用量でメモリが不足するか、ひどくクラッシュするかを交互に繰り返すまで、3年間は問題ありませんでした。

現在、ソリューションは概念的に単純でした。DBからバッチでデータを取得できるようにします。そうすることはインテリジェントに機能しました。しかし、元の設計段階で余分な数週間の作業があったとしたら、パフォーマンスが3か月の試練に変わることを考えていたとしたら、すべての小さな関数、オブジェクト、API、およびアーキテクチャ全体が「100%データがあります」。

一般に、データの量がパフォーマンスの問題であり、データのチャンク化が主な実行可能なソリューションである状況では、そのチャンク化は先行するように設計する必要があります。

于 2009-10-10T15:02:05.343 に答える
2

これが、経験豊富なソフトウェア エンジニアとソフトウェア初心者の違いを生むものだと思います。

経験豊富なソフトウェア エンジニアは、設計のパフォーマンスの問題を常に念頭に置く必要があります。

例: モジュール内に O(n^3) のパフォーマンス動作を持つアルゴリズムがあり、n が増加する可能性がある場合、状況によってモジュールが非常に遅くなるという状況が発生する可能性があります。

もちろん、多くの違いがあります。インメモリ配列に O(n^3) がある場合、ディスク操作で O(n^2) として問題が少ない可能性があります。

したがって、これらのことについて考え、設計を変更する必要がある場所や、後で微調整することで問題なく高速化できる場所を決定するには、経験が重要です。

于 2009-10-10T14:17:55.527 に答える
2

少しでもパフォーマンスが重要であることを最初から知らない限り、優れたオブジェクト指向の原則を採用することをお勧めします。

一般に、大きなパフォーマンスの向上は、アーキテクチャの再構築ではなく、アルゴリズムの最適化によって達成されます (アーキテクチャが通常のベスト プラクティスに従っている限り)。扱いにくい設計を選択することで得られるパフォーマンスの向上は、最もパフォーマンスが要求される環境以外ではほとんどの場合無関係です。そのため、最初から絶対的な最高のパフォーマンスが必要でない場合は、適切な OO を使用してください。

于 2009-10-10T14:12:19.903 に答える
1

OOP のベスト プラクティスに従い、設計パターンを幅広く使用する適切に設計されたソフトウェアは、保守性に優れているか、または原則として保守性が高い必要があります。現在、低レベルの最適化が実際の役割を果たしていることはまれであり、CPU とリソースは非常に過剰です。

再利用可能、保守可能、スケーラブルなコードのみ。低レベルの最適化に対するさらなる実際のニーズは、このような優れた環境で簡単に実装できます。本当に必要な時だけ、本当にこの問題に対処する時が来た時だけ。

于 2009-10-10T14:08:44.810 に答える
0

ほとんど「依存する」方法で、要件が何であるかを本当に考慮する必要があると思います。最も優先度の高い要件の 1 つが「途方もないレベルのスループット/パフォーマンスを維持できなければならない」場合、全体的なアーキテクチャとテクノロジの選択において、それを事前に計画および設計しないのはおかしいでしょう。

于 2009-10-10T15:31:49.417 に答える
0

Mikael Auno だけが「要件」という言葉に言及したのは興味深いことです。

Knuth の見積もりはTRVTH ですが、すべては要件に帰着します。スケーラビリティもその 1 つですか? 予想負荷は?「わからない」と答えた場合は、質問してください。

これらが要件である場合は、受け入れテストに負荷テストを追加します。

あなたはまだ保守性のために設計したいと思っています。パフォーマンスに関する考慮事項はLast Responsible Momentまで延期し、次にプロファイルを作成します - 推測しないでください。マイクロ最適化は、会社のお金の無駄遣いです。

責任の瞬間がかなり早い時期に発生することがあります。すべてのデータが XML ファイルとしてディスクに保存されるエンタープライズ CRM システムを設計するつもりはありません。私やろうとしているのは、永続層を抽象化することです。

最後に、コリブリのコメントは正しいです。答えは(いつものように)「場合による」です。

編集:再読すると、「ソフトウェアが実行されることが期待される環境にすべて依存すると言って、私に答えないでください」というOPの制約に違反したのではないかと思います。しかし、私は私の答えを支持します。要件が変更された場合、通常、単純な設計の方が変更が容易です。明示されていない仮定は、要件がどのように変化するかを事前に知っているということです。要求は、「桁違いにスケーリングする」または「組織間での顧客の移動を許可する」である可能性があります。前者を設計すると、後者の実装が難しくなる可能性があります。

于 2009-10-10T15:31:59.183 に答える
0

事前に最適化を行わないでください。しかし、アーキテクチャは、システムの潜在的なパフォーマンスに大きな影響を与えます。

次の本を読むことをお勧めします: Release It!: Design and Deploy Production-Ready Software

于 2009-10-11T10:00:55.877 に答える
0

保守性を犠牲にしてではなく、常に非効率よりも効率を目指すべきです。そうです、効率を考慮して設計する必要がありますが、時期尚早の最適化には注意が必要です。ドナルド・クヌースからのお気に入りの引用:

「私たちは小さな効率を忘れるべきです。たとえば、約 97% の確率で: 時期尚早の最適化はすべての悪の根源です。」

于 2009-10-10T14:04:09.797 に答える