開発者は、最初に読みやすさやパフォーマンスを目指す必要がありますか?[閉まっている]


82

多くの場合、開発者は、問題を解決するための2つの可能な方法から選択する必要があります。1つは慣用的で読みやすい方法で、もう1つは直感的ではないがパフォーマンスが向上する可能性があります。たとえば、Cベースの言語では、数値に2を掛ける方法は2つあります。

int SimpleMultiplyBy2(int x)
{
    return x * 2; 
}

そして

int FastMultiplyBy2(int x)
{
    return x << 1;
}

最初のバージョンは、テクニカルリーダーと非テクニカルリーダーの両方で簡単に選択できますが、ビットシフトは乗算よりも簡単な操作であるため、2番目のバージョンの方がパフォーマンスが向上する可能性があります。(今のところ、コンパイラのオプティマイザがこれを検出して最適化しないと仮定しましょう。ただし、これも考慮事項です)。

開発者として、最初の試みとしてどちらが良いでしょうか?


少し厳しい。私たち全員が時々抱える懸念についての良い質問です。1
Inisheer

3
この例は明らかに不自然で些細なものです。ハードコードされた乗数を使用した関数は実際にはありません。
JohnMcG 2008年

1
重要なのは、「<は<=よりもパフォーマンスが優れているか」などの質問がたくさんあることです。これは間違った質問です。正しい(最初の)質問は、慣用的なものか従来のものか、次にパフォーマンスについて心配することです。
JohnMcG 2008年

1
これは私がstackoverflowで読んだ最高の質問の1つです。これは、言語のセマンティクスだけでなく、コンピューターの動作方法の要点になります。+1
WolfmanDragon 2008年

2
@OutlawLemur私はそれを知っています。しかし、たとえば、<または<=を使用してループを構築する方がよいかどうかを尋ねる人もいます(後者の場合、比較値は事前にインクリメントされます)。
JohnMcG 2012年

回答:


109

あなたは1つを逃した。

正確さのために最初のコード、次に明確にするために(もちろん、2つはしばしば接続されています!)。最後に、実際に必要な実際の経験的証拠がある場合にのみ、最適化を検討できます。時期尚早の最適化は本当に悪です。ほとんどの場合、最適化には時間、明快さ、保守性が必要です。それで価値のあるものを購入していることを確認したほうがいいでしょう。

優れたアルゴリズムは、ほとんどの場合、ローカライズされたチューニングよりも優れていることに注意してください。正しく、明確で、高速なコードを入手できない理由はありません。しかし、「速い」ことに焦点を合わせてそこに着くのは不当に幸運です。


これは、ここでの最良の答えです。コードではなく、アルゴリズムを微調整します。微妙な変更を加えることで、jscript Sieve ofErastosthenesを他の点では同一のC ++バージョンよりも優れたパフォーマンスにすることができます。(私自身の方法である
アトキン

2
残念ながら、お気に入りの回答はできません。:)
Sandor Davidhazi 2008年

59

パフォーマンスが測定され、より高速なバージョンが必要になるまで、IMOは最初に明らかに読み取り可能なバージョンです。


同意する。昨年、私は会社のサーバー側Javaコードベースの一部として主要なコンポーネントを実装し、読みやすくするために最善を尽くしました。その後、パフォーマンスの問題が発生し、デザインを大幅に作り直したため、いくつかの点で少し読みにくくなりました。
Ryan Delucchi 2008年

46

ドン・クヌースからそれを取る

時期尚早の最適化は、プログラミングにおけるすべての悪(または少なくともそのほとんど)の根源です。


引用はドン自身からではなく、ホアからです。ドンはそれを人気にした。ウィキペディアを確認してください。
kohlerm 2008年

1
そして、それは段落全体からの1つの条項の選択的な引用であり、いくつかの非常に重要な資格が含まれています。
user207421 2016年

19

読みやすさ100%

コンパイラが "x * 2" => "x << 1"の最適化を実行できない場合は、新しいコンパイラを入手してください。

また、プログラムの時間の99.9%は、ユーザー入力の待機、データベースクエリの待機、およびネットワーク応答の待機に費やされていることを忘れないでください。20億回の倍数を実行しない限り、それは目立たないでしょう。


8

あなたの与えられた例では、そこにあるコンパイラの99.9999%が両方の場合に同じコードを生成します。これは私の一般的なルールを示しています-最初に読みやすさと保守性のために書き、必要なときにだけ最適化してください。


Cコンパイラは、示されている2つの例の異なるアセンブリコードにコンパイルされます。1つ目はループを作成し、2つ目は左シフト命令を作成します。これはすべてのCスタイルのコンパイラに当てはまるはずです。私はそれぞれをテストしていないので、それについて約束することはできません。
WolfmanDragon 2008年

この特定の例では、確かに。そうでない場合がたくさんあるので、一般的な質問はまだ良い質問です
Mark Ba​​ker

@WolfmanDragon、一体何を言ってるの?「* 2」がループを生成するのはなぜですか?「gcc-O2-s」で試してみると、どちらの場合もaddl命令が表示されます。
Paul Tomblin

1
コンパイラがその関数でループを作成する場合は、別のコンパイラを入手することをお勧めします。
Martin Vilcans 2009

8

確かに読みやすさ。誰かが文句を言わない限り、速度について心配しないでください


8

読みやすさ。

パフォーマンスのコーディングには、独自の課題があります。ジョセフ・M・ニューカマーはよく言った

最適化は、重要な場合にのみ重要です。それが重要であるとき、それは非常に重要ですが、それが重要であることがわかるまで、それをするのに多くの時間を無駄にしないでください。それが重要であると知っていても、それがどこで重要であるかを知る必要があります。パフォーマンスデータがないと、何を最適化するかわからず、おそらく間違ったものを最適化することになります。

結果はあいまいで、書きにくく、デバッグしにくく、問題を解決しないコードを維持するのが難しくなります。したがって、(a)ソフトウェア開発とソフトウェア保守のコストが増加すること、および(b)パフォーマンスへの影響がまったくないことの2つの欠点があります。


5

読みやすさ。最適化する時期は、ベータテストを開始するときです。そうでなければ、あなたはあなたが時間を費やす必要があるものを本当に知ることは決してありません。


5

私は最初に読みやすさを求めます。最近のような最適化された言語と大量にロードされたマシンを使用すると、読みやすい方法で記述したコードのほとんどが適切に実行されます。

いくつかの非常にまれなシナリオでは、パフォーマンスのボトルネックが発生することがかなり確実であり(過去の悪い経験からのものである可能性があります)、パフォーマンスを大幅に向上させることができる奇妙なトリックを見つけることができました。それ。ただし、そのコードスニペットには非常によくコメントする必要があります。これにより、コードスニペットが読みやすくなります。


4

この議論で見過ごされがちな要因は、プログラマーが読みにくいコードをナビゲート、理解、変更するのに余分な時間がかかることです。プログラマーの時間が1時間に100ドル以上かかることを考えると、これは非常に現実的なコストです。
パフォーマンスの向上は、開発におけるこの直接的な追加コストによって相殺されます。


4

説明付きのコメントをそこに置くと、読みやすく高速になります。

それは本当にプロジェクトの種類とパフォーマンスの重要性に依存します。3Dゲームを構築している場合、通常、途中でそこに投入したい一般的な最適化がたくさんあり、そうしない理由はありません(早めに夢中になりすぎないでください)。しかし、あなたがトリッキーなことをしているなら、それをコメントしてください。そうすれば、それを見ている人は誰でもあなたがトリッキーである方法と理由を知ることができます。


3

答えは状況によって異なります。たとえば、デバイスドライバーのプログラミングやゲーム開発では、2番目の形式が受け入れられるイディオムです。ビジネスアプリケーションでは、それほど多くはありません。

最善の策は、コード(または同様の成功したアプリケーション)を調べて、他の開発者がどのように実行しているかを確認することです。


3

<<を使用すると、マイクロ最適化が行われます。したがって、Hoareの(Knutsではない)ルール:

時期尚早の最適化はすべての悪の根源です。

適用され、そもそもより読みやすいバージョンを使用する必要があります。

これは、IMHOが、拡張できない、またはうまく機能しないソフトウェアを設計するための言い訳として誤用されることが多いルールです。


3

どちらも。コードは両方のバランスを取る必要があります。読みやすさとパフォーマンス。どちらかを無視すると、プロジェクトのROIが台無しになります。これは、結局のところ、上司にとって重要なことです。

読みやすさが悪いと保守性が低下し、保守に費やされるリソースが増え、ROIが低下します。

パフォーマンスが悪いと、投資と顧客ベースが減少し、ROIが低下します。


2

コードベースが大きいほど、読みやすさが重要になります。いくつかの小さな機能を理解しようとすることはそれほど悪くはありません。(特に、例のメソッド名が手がかりを与えてくれるので。)コーディングをやめたばかりの孤独な天才によって書かれた、彼の能力の複雑さの頂点をついに見たという壮大なユーバーコードにはあまり適していません。あなたのために書いた、そしてあなたはそれを決して理解しないでしょう。



2

常に最大限に最適化する必要があり、パフォーマンスは常に重要です。 今日私たちがブロートウェアを持っている理由は、ほとんどのプログラマーが最適化の仕事をしたくないからです。

そうは言っても、巧妙なコーディングで明確にする必要がある場所にはいつでもコメントを入れることができます。


ある程度は同意します。元の質問で述べたようなマイクロ最適化を行うべきではないと思います。リソースを最適な方法で使用するようにシステムを設計する必要があります。その分野で得られるパフォーマンスははるかに多くあります。
Erik van Brakel

今日はブロートウェアがありますが、最適化されていないことを非難することはありません。私はそれを過剰設計、バズーカでハエをたたく、手漕ぎボートだけが必要なときに遠洋定期船を作ることで非難します。そしてもちろん、それは大変なことです。
Mike Dunlavey 2008

デザインの最適化が最優先事項であるという点で、私はあなたの両方に同意します。また、ソフトウェアエンジニアリングプロセスのすべてのレベルに同じ態度を適用する必要があるとも言えます。コードレベルで最適化をわざわざ行わないのであれば、設計中にも不足している可能性があります。
ランスロバーツ

2

私はグーグルで働いていないので、私は邪悪なオプションを選びます。(最適化)

Jon Bentleyの「ProgrammingPearls」の第6章では、6つの異なる設計レベルで最適化することにより、1つのシステムが400倍高速化された方法について説明しています。これらの6つの設計レベルでのパフォーマンスを気にしないことで、最新の実装者はプログラムで2〜3桁の速度低下を簡単に達成できると思います。


1

ビットシフトと乗算は、ほとんど何もられない簡単な最適化です。そして、指摘されているように、あなたのコンパイラはあなたのためにそれをするべきです。それ以外は、この命令が実行されるCPUと同様に、ゲインは無視できます。

一方、本格的な計算を実行する必要がある場合は、適切なデータ構造が必要になります。しかし、問題が複雑な場合は、それを見つけることが解決策の一部です。例として、1000000のソートされていないオブジェクトの配列でID番号を検索することを検討してください。次に、バイナリツリーまたはハッシュマップの使用を再検討します。

ただし、n << Cのような最適化は通常無視でき、いつでも変更するのは簡単です。コードを読みやすくすることはできません。


1

解決する必要のあるタスクによって異なります。通常、読みやすさの方が重要ですが、そもそもパフォーマンスについて考えると、まだいくつかのタスクがあります。また、最適化自体ではコードの十分な部分を最初から書き直す必要がある場合があるため、すべてが完全に機能した後、1日またはプロファイリングと最適化に費やすことはできません。しかし、それは今日では一般的ではありません。


1

ボトルネックがわからなければ、最適化しても意味がありません。コードのその部分がほとんど実行されないことを見つけるためだけに(通常はある程度の可読性を犠牲にして)関数を信じられないほど効率的にしたかもしれません。したがって、測定するものができるまでマイクロ最適化することはできません。そうすれば、読みやすさから始めたほうがよいでしょう。ただし、アーキテクチャ全体を設計するときは、速度と理解しやすさの両方に注意する必要があります。どちらも大きな影響を及ぼし、変更が難しい場合があるためです(コーディングスタイルと方法によって異なります)。


1

ソフトウェアのコストの約70%がメンテナンスに費やされていると推定されています。読みやすさにより、システムの保守が容易になるため、ソフトウェアの耐用年数にわたってコストが削減されます。

パフォーマンスが読みやすさよりも重要である場合があります。

読みやすさを犠牲にする前に、「私(またはあなたの会社)は、これを行うことによってシステムに追加する追加コストに対処する準備ができていますか?」と考えてください。


1

ほとんどの人が答えで言ったように、私は読みやすさを好みます。私が実行している100のプロジェクトのうち99は、厳しい応答時間の要件がないため、簡単に選択できます。

コーディングを始める前に、すでに答えを知っている必要があります。一部のプロジェクトには、「タスクXをY(ミリ)秒で実行できる必要がある」などの特定のパフォーマンス要件があります。その場合は、取り組む目標があり、最適化する必要があるかどうかがわかります。(うまくいけば)これは、コードを書くときではなく、プロジェクトの要件段階で決定されます。

読みやすさと後で最適化する機能は、適切なソフトウェア設計の結果です。ソフトウェアがサウンドデザインである場合、システムの他の部分を壊すことなく、ソフトウェアの一部を分離し、必要に応じてそれらを書き直すことができるはずです。その上、私が遭遇した最も真の最適化のケース(いくつかの実際の低レベルのトリックを無視して、それらは偶発的です)は、あるアルゴリズムから別のアルゴリズムに変更するか、ディスク/ネットワークではなくメモリにデータをキャッシュすることでした。


1

読みやすさが最初の目標です。

1970年代に、陸軍はソフトウェア開発の当時の「新しい」技術のいくつか(トップダウン設計、構造化プログラミング、チーフプログラマーチームなど)をテストして、統計的に有意な違いをもたらしたものを特定しました。

開発に統計的に有意な違いをもたらした唯一の手法は...

プログラムコードへの空白行の追加。

これらの事前構造化された事前オブジェクト指向コードの可読性の向上は、生産性を向上させたこれらの研究の唯一の手法でした。

==============

最適化は、プロジェクト全体が単体テストされ、計測の準備ができている場合にのみ対処する必要があります。コードを最適化する必要がある場所がわかりません。

1970年代後半のKerniganand Plaugerの画期的な本で、SOFTWARE TOOLS(1976)とSOFTWARE TOOLS IN PASCAL(1981)は、トップダウン設計を使用して構造化プログラムを作成する方法を示しました。彼らはテキスト処理プログラムを作成しました:エディター、検索ツール、コードプリプロセッサー。

完成したテキストフォーマット機能がINSTRUMENTEDされたとき、彼らは処理時間のほとんどがテキストの入出力を実行する3つのルーチンに費やされていることを発見しました(元の本では、io関数は89%の時間を要しました。パスカルブックでは、これらの関数は55%消費しました!)

彼らはこれらの3つのルーチンを最適化することができ、合理的で管理しやすい開発時間とコストでパフォーマンスの向上の結果を生み出しました。


1

読みやすさを第一に。しかし、特にデータ構造の観点からは、読みやすさだけではありません。

なぜこんなに遅いのか理解できなかった、視覚分析プログラムをやっている学生を思い出しました。彼は単に良いプログラミング慣行に従っただけです-各ピクセルはオブジェクトであり、それはその隣人にメッセージを送ることによって機能しました...

これをチェックしてください


1

読みやすさがなければ、本当に必要なときにパフォーマンスを向上させるのは非常に困難です。

パフォーマンスは、プログラムに問題がある場合にのみ改善する必要があります。この構文ではなく、ボトルネックになる場所がたくさんあります。<<で1nsの改善を求めているが、その10分のIO時間を無視したとします。

また、読みやすさに関しては、プロのプログラマーがコンピューターサイエンスの用語を読んだり理解したりできる必要があります。たとえば、putThisJobInWorkQueueと言う必要はなく、メソッドにenqueueという名前を付けることができます。


私は同意しますが、あなたには悪い例があると思います。たとえば、コードベースについて何も知らない人として、エンキューは私にとってあまり意味がありません。どうしたらいいのかわからない、何を知りたいのか。あなたが与えた例は、何がはるかに優れているかを示しています。
ショーンスウィート

0

最初に読みやすさのために書いてください、しかし読者がプログラマーであることを期待してください。自分の塩に値するプログラマーは、乗算とビットシフトの違いを知っているか、適切に使用されている三項演算子を読み、複雑なアルゴリズムを調べて理解できる必要があります(コードにコメントしていますか? )など。

もちろん、初期の過剰最適化は、後でリファクタリングが必要になったときに問題が発生するのは非常に悪いことですが、個々のメソッド、コードブロック、またはステートメントの最適化には実際には当てはまりません。


0

私は読みやすさのために行くと思います。

しかし、与えられた例では、関数の名前が関数で何が起こっているかを正確に示しているので、2番目のバージョンはすでに十分に読み取り可能であると思います。

私たちがいつも私たちに教えてくれる機能を持っていたら、それらは何をしますか...


0

1時間のプロセッサ時間はどれくらいの費用がかかりますか?

1時間のプログラマーの時間はどれくらいの費用がかかりますか?


1
エンドユーザーの1時間の時間はどのくらいかかりますか?これをユーザー数で変更します。
gbjbaanb 2008年

gbjbaanb:私の考えは正確です。Andyのコメントは、エンドユーザーが目にすることのないサービスに対してのみ機能し、それでも良い比較にはなりません。
Erik van Brakel

0

私見両方のことは何の関係もありません。最初に機能するコードを探す必要があります。これは、パフォーマンスや読み取りの程度よりも重要だからです。読みやすさについて:どのような場合でも、コードは常に読みやすくする必要があります。

ただし、コードが読み取れず、同時に優れたパフォーマンスを提供できない理由がわかりません。あなたの例では、2番目のバージョンは最初のバージョンと同じくらい読みやすいです。それについて読みにくいものは何ですか?プログラマーが左にシフトすることは2の累乗で乗算することと同じであり、右にシフトすることは2の累乗で除算することと同じであることを知らない場合...まあ、一般的な読みやすさよりもはるかに基本的な問題があります。

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