いつパフォーマンスを気にする必要がありますか?


16

JavaのIRCチャンネル、SO、およびその他の場所で最も長い間、「コードの見た目とその読みやすさ/理解しやすさ、そして絶対に必要な場合は後でパフォーマンスについて心配する」という行に沿って何かを言われました。そのため、私は長い間、小さなデスクトップまたはWebアプリのパフォーマンスについてOCDを実際に使ったことがなく、明らかに非効率なものを削除していました。

ほとんどの応答は「スケーラビリティについてはどうですか?」です。これは正当なポイントですが、アプリが10,000行のファイルを解析するためだけに構築されている場合、1,000,000行のファイルを押し込む人のごく一部のコードを混乱させるべきですか?

私の主な質問は、非常に速く物事を行うが、アップグレードの可能な方法を破壊し、コードを過度に困難にし、とにかく次の開発者によって書き直しがちな巨大で複雑な獣のために、タスクを行う簡単だがやや非効率的な方法を交換すべきときですか?

回答:


23

問題になったときのパフォーマンスが心配です。

10,000行のファイルを処理する小さなアプリを作成し、100番目のファイルごとに1,000,000行のファイルを取得する場合、その1つのファイルの処理に時間がかかることはおそらく問題ではありません。ただし、最初の5〜10倍のサイズのファイルを定期的に取得していて、アプリケーションの処理に時間がかかりすぎる場合は、プロファイリングと最適化を開始します。

今、私は「仕事をするには長すぎます」と言った。それは、ユーザーまたはスポンサー組織が決定します。タスクを実行していて、ソフトウェアなしで、または別のツールを使用して3分かかったときに、何かをするのに5分かかる場合、おそらくバグレポートまたはメンテナンスリクエストを提出して改善します。

あなたがユーザーである場合、あなたのソフトウェアがその仕事をするのにどれくらいの時間がかかるかはあなた次第です-あなたがそれをより速くしたいのか、より読みやすいコードを得るためにもっと長く待つかどうかはあなただけが決めることができます。



プロファイリングと最適化を開始します1)ジョブに時間がかかる2)ハードウェアリソースの1つが最大(例:100%cpu)
A. Binzxxxxxx

10

私の主な質問は、非常に速く物事を行うが、アップグレードの可能な方法を破壊し、コードを過度に困難にし、とにかく次の開発者によって書き直しがちな巨大で複雑な獣のために、タスクを行う簡単だがやや非効率的な方法を交換すべきときですか?

これは通常、誤った二分法です。驚くほど効率的で、読みやすく、保守可能なコードを書くことができます。素晴らしく非効率的で維持できない混乱の山を書くことができます。

パフォーマンスの問題を扱うとき、私は通常、解決しようとしているビジネス上の問題について考えようとします。顧客が使用するとき、ソフトウェアはどのように動作しますか。私のアプリケーションのパフォーマンスはJacob Nielsenを幸せにしますか?


5
++偽の二分法!彼らは決して学ばないでしょうか?パフォーマンスの問題を見つけて修正すると、コードが速くなるだけでなく、改善されます。私はただ一つだけの賛成票を持っていることを後悔しています!
マイクダンラベイ

+1は、それが通常は誤った二分法であると書いて...常にではありませんが、通常は。
ダンローゼンスターク

1
-1を書くことは通常、誤った二分法です。事実は、通常は正しいことであり、まれな場合にのみ誤った二分法です。プログラミングキャリアの30年以上で、「意図した」パフォーマンスの最適化が多すぎて、実際にはコードの理解と保守が難しくなりました(そして、最適化する必要のないものを最適化することがよくありました)。
Doc Brown

5

大学でマイクロプロセッサの勉強を始めた私は、「一般的なケースを迅速に作成し、一般的でないケースを修正してください。」

ユーザーがごくわずかな割合で、コードが意図したものよりも2桁大きい入力でコードを窒息させている限り、気にしないでください。十分な時間を与えた場合は入力を正しく処理し、終了前にジョブを強制終了した場合に破損したものが無駄にならないようにします。

しかし、ますます多くの人々がそのように使用し始めます(または、「あなたが私の毎週のTPSレポートで書いたツールを使用したいのですが、それはすべておかしい日がかかります」)パフォーマンスの向上のためにメンテナンスの容易さを犠牲にすることを検討し始めます。


1

私の主な質問は、非常に速く物事を行うが、アップグレードの可能な方法を破壊し、コードを過度に困難にし、とにかく次の開発者によって書き直しがちな巨大で複雑な獣のために、タスクを行う簡単だがやや非効率的な方法を交換すべきときですか?

「コードの見た目とその読みやすさ/理解しやすさ、そして絶対に必要な場合のパフォーマンスについて心配する」は簡単な方法であり、一般的には役に立ちません。優れたデザインは、維持しやすく、読みやすく、効率的です。

パフォーマンスは、優れた設計の一般的なコンポーネントの1つです。プログラムが遅くて無駄が多い場合、実際には再利用できません。その混乱を修正する必要がある場合、クライアントが更新するのに時間がかかりすぎない限り、クライアントの更新を強制します。その遅いプログラムは、改善するにはコストがかかりすぎる大きな混乱になります。それが彼らのニーズに合わないので、彼らは代替を選択します。悪いデザインの改善の副作用の診断、更新、および対処は、それを書く最初の開発時間よりも効率的で、正しく動作し、一般的に良いデザインになっていることがよくあります。そのプログラムは非常に再利用可能であり、低いメンテナンス(win)が必要です。

したがって、あなたの質問に対する簡単な答えは、「無駄にしないでください。再利用のために書いてください。概念の証明をプロトタイピング/開発するときは怠けても構いませんが、実動コードにはそのプロトタイプを使用しないでください。」

生産プログラムや再利用する予定のプログラムを作成するときは、無駄な設計を認識し、避けてください。実装中はプログラムが無駄にならないように書くのに理想的な時期です。詳細とその操作について明確な考えを持っているので、書いた後に修正するのは本当に苦痛で効果がありません。多くの人は、最後に小さなプロファイル(おそらく)があると考えています。問題がある場合は通常、再設計/変更に時間がかかりすぎ、非効率性が非常に多く、プログラムを理解できないほどです。プロファイルの結果に基づいています。このアプローチは、実装中にほとんど時間がかかりません(これを十分に行ったと仮定すると)。通常、設計は数倍速くなり、より多くのコンテキストで再利用できます。無駄ではない 適切なアルゴリズムを選択し、実装を考え、適切な実装を再利用することは、すべて優れた設計のコンポーネントです。全てが読みやすさ、保守性、および再利用が、痛むよりも頻繁に改善されます。


0

私はコードを読みやすくしようとしています-パフォーマンスが酷評されています。

コードが遅すぎることが判明した場合、それがリファクタリングされて、より高速になります。コードは読みにくい傾向があるため、通常はリファクタリングプロセスの後に多くのコメントが続きます。


0

うーん-決して?

真剣に、コードは常に簡単に理解され維持されるように書かれるべきです。

パフォーマンスの問題をいつ処理するかについては、問題を特定したら対処します。コードを事前に最適化しないでください。パフォーマンスの問題がどこにあるかを推測するだけです。

コードが明確、簡潔、理解可能、および保守可能になるように記述されている場合、ユーザーまたは他のプログラマーがコードをリファクタリングして問題を解決する必要はありません。


3
私はこれに同意しません。パフォーマンス要件は、システムの有効な非機能要件です。
トーマスオーエンズ

技術的には、パフォーマンスに関連する要件が明確に定義されている場合、パフォーマンスの問題を特定し、ソリューションでそれを考慮する必要があると言えます。私が話しているのは、非特定の「潜在的な」問題を回避できるように、事前に賢くすることです。
ノアグッドリッチ

あ。ええ、その場合は絶対に正しいです。非常に多くの可能性について心配する必要はありませんが、あなたが知っていることに集中してください。
トーマスオーエンズ

0

私は通常、何よりもまず読みやすいコードを書きます。プログラムの実行が遅すぎて仕事を果たせない場合にのみ、プロファイルを作成して最適化します。とは言っても、コードの可読性に影響を与えない一般的な最適化を実行する習慣を身につけても何も問題はありません。つまり、コードの一部を2つの同等に(またはほぼ同等に)読み取り可能な方法で記述できる場合、通常は高速なコードを選択します。

たとえば、Pythonでは、リスト内包表記(またはジェネレーター式)は同等のforループよりも高速になる傾向があるため、読みやすさに影響しない場合はリスト内包表記を使用します(たとえば、リスト内包表記を入れ子にしない場合、私はそれを避けることができ、ネストされたリストの内包表記は精神的に解析するのが難しいため、代わりにforループを使用します)。

同様に、不変データ型は可変データ型よりも高速になる傾向があるため、可能な場合は不変データ型を使用します。


0

本当にパフォーマンスが重要な領域で作業している場合、後から考えて効率を先送りすることはできません。これらの場合、および最終結果の保守性に関連する方法で早期に設計する場合に考えることは、最も重要なことの1つです。

大規模なサーバーを設計して実装することはできず、システム全体をロックして個々のクライアント要求を処理せずにロックするグローバルスレッドロックを使用して、すべてのブロック関数を使用するだけの簡単で十分に文書化されたコードの記述から始めることはできません共有状態、スレッドの競合、非同期性について考えました。これは災害のレシピであり、あなたが書いた素敵に文書化されたコードの大部分を再設計し、書き直さなければなりません。効率的でシンプルな作業設計を前もって考えていたのではなく、後知恵で必要な効率を達成します。

32コアの最高速度のハードウェアで1秒あたり2フレームしか動作せず、画面がビジーになるたびに15秒間ストールする傾向があるエンジンを使用して、8か月でゲーム開発チームが制作を開始1つの小さなローカライズされたホットスポットを修正します。コードベースの隅々にまで及ぶ可能性のある、図面ボードと設計変更の壮大な再訪を保証する方法で、設計がFUBARである可能性があります。

John Carmackと共に、彼は技術デモを実稼働環境に統合するために、毎秒最低数百から数千フレームで実行する方法について一度話しました。それは効率に対する不健全な執着ではありません。彼は、顧客がゲームを受け入れられるようにするには、ゲーム全体を30+ FPSで実行する必要があることを事前に知っています。その結果、ソフトシャドウシステムのような小さな側面は30 FPSで実行できません。さもないと、ゲーム全体が必要なリアルタイムフィードバックを提供するのに十分な速度にならない可能性があります。それはだ使用できない、それは必要な効率を達成するまで。効率のための基本的な要件があるようなパフォーマンスが重要な領域では、適切な速度を達成できないソリューションは、実際にはまったく機能しないソリューションよりも優れています。。また、その効率性について多くのことを事前に考えない限り、リアルタイムゲームエンジンに必要な1秒あたり数百から数千フレームで実行する効率的なソフトシャドウシステムを設計することはできません。実際、このような場合、パストレースを使用してフレームあたり2時間で正常に機能するソフトシャドウシステムを考えるのは簡単なため、作業の90 +%が効率に重点を置いていますが、調整することは期待できませんアプローチにまったく異なる変更を加えることなく、毎秒数百フレームで実行します。

効率がアプリケーションの設計の基本的な部分である場合、後知恵で機能する設計を達成することは期待できないため、それを無視することで節約したよりも劇的に多くの時間を失うことなく、後知恵で効率を達成することは期待できません。「デザインについて考えることを後回しにすることは許されません。コードを適切に文書化するだけで、後で適切なデザインを思いつくことができます。」しかし、パフォーマンスが重要なアーキテクチャでは、効率的な設計を事前に細心の注意を払わなければ、それが効果的に行われます。

これは、実装をすぐに微調整する必要があるという意味ではありません。実装の詳細については、設計を変更する必要がなければ、測定後に高速ソリューションに向けて反復する余地が多くあります。多くの場合、それが最も生産的な方法です。しかし、設計レベルでは、設計とアーキテクチャが最初から効率にどのように関係するかを十分に検討する必要があります。

ここでの主な違いはデザインです。デザインが依存関係を蓄積するため、後から見たデザインに大きな変更を加えることは容易ではなく、デザインが変更されると依存関係が壊れます。そして、デザインが合理的に効率的である必要がある場合、または場合によってはその品質が効率によって大部分が測定されるという要件がある場合、適切なデザインを後から考えて達成できると期待すべきではありません。オペレーティングシステム、コンパイラ、ビデオプロセッサ、レイトレーサー、ゲームエンジン、物理エンジンなど、効率が品質の大きな側面である競合製品では、効率とデータ表現に関する考えが最初から綿密に考えられていました。そして、そのような場合、事前に効率性に多くの考えを入れるのは時期尚早な最適化ではありません。そのような考えを最も生産的な時期に正確に配置し、

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