コーディングの際にマイクロ最適化は重要ですか?


178

最近、PHPでisset()がstrlen()よりも高速だった理由を調べるために、Stack Overflowについて質問しました。これにより、読み取り可能なコードの重要性と、コードのマイクロ秒のパフォーマンスの改善が考慮に値するかどうかについて疑問が生じました。

私の父は退職したプログラマーであり、私は彼に応答を示しました。彼は、コーダーがマイクロレベルでもコードのパフォーマンスを考慮しない場合、優れたプログラマーではないことを完全に確信していました。

確かではありません-おそらく計算能力の向上は、この種のマイクロパフォーマンスの改善を考慮する必要がなくなったことを意味しますか?おそらく、この種の検討は実際の言語コードを書く人次第でしょうか?(上記の場合のPHPの)。

環境要因が重要になる可能性があります-インターネットは世界のエネルギーの10%を消費します。何百万ものウェブサイトで何兆回も複製されると、数マイクロ秒のコードがどれだけ無駄になるのだろうか?

できればプログラミングに関する事実に基づいて答えを知りたいです。

コーディングの際にマイクロ最適化は重要ですか?

25の答えの私の個人的な要約、すべてに感謝します。

非常にまれな状況でのみ、マイクロ最適化について本当に心配する必要がある場合があります。ほとんどの場合、信頼性と読みやすさがはるかに重要です。ただし、ときどきマイクロ最適化を検討しても害はありません。基本的な理解は、次のようなコーディングの際に明らかに悪い選択をしないようにするのに役立ちます。

if (expensiveFunction() || counter < X)

あるべき

if (counter < X || expensiveFunction())

@ zidarsk8の例)これは安価な関数である可能性があるため、コードを変更するとマイクロ最適化になります。しかし、基本的に理解していれば、そもそも正しく書くことができるので、その必要はありません。


123
あなたのお父さんのアドバイスは時代遅れです。パフォーマンスがどれだけ向上するかは尋ねません。ボトルネックはどこにあるのか尋ねます。コードのセクションのパフォーマンスを改善しても、全体的な違いがない場合は問題ではありません。最も遅いリンクが速度を決定します。PHPでは、これはネットワークへの書き込みです(他の方法でIE測定を証明できる場合を除く)。より読みやすいコードを書くことに変換することはより重要です。
マーティンヨーク

61
キーワードが考慮される場合、彼は間違っていません。あなたはそれについていくつかの手がかりを持っている必要があります。
ジェフ

37
有名な時期尚早の最適化の引用がまだ言及されていないため、私は悲しいです:「プログラマーは、プログラムの重要でない部分の速度について考える、または心配するのに膨大な時間を浪費します。デバッグとメンテナンスが考慮されるときの影響。小さな効率、時間の約97%を忘れてください。時期尚早な最適化はすべての悪の根源です。しかし、その重要な3%で機会を逃してはなりません。
タマラWijsman

13
「世界のエネルギーの10%」に関する情報源を提供できますか?
マイケルイースター

17
coder does not consider performance in their code even at the micro level, they are not good programmersマイクロ最適化とは大きく異なります。それはちょうど良いコーディングです。
woliveirajr

回答:


90

私はあなたの父親に賛成と反対です。パフォーマンスは早期に検討する必要がありますが、マイクロ最適化は、CPUにバインドされた小さなセクションのコードに高い割合の時間が費やされることが実際にわかっている場合にのみ、早期に検討する必要があります。

マイクロ最適化の問題は、通常、プログラムが実際に必要以上の時間をどのように費やすかという概念がなくても行われることです。

この知識は、この例のように、パフォーマンスチューニングを行った経験から得られます。この例では、明らかな非効率性のない一見単純なプログラムが、最初の43倍高速になるまで、一連の診断と高速化のステップを経て実行されます。

それが示すことは、問題がどこにあるかを本当に推測したり、直観したりできないことです。私がランダムに一時停止する診断を実行すると、かなりの時間を占めるコード行が優先的に公開されます。それらを見ると、代替コードが見つかる可能性があり、それによって全体の時間をおよそその分だけ短縮できます。

あなたが修正しなかった他の事柄は以前と同じくらい時間がかかりますが、全体の時間が短縮されたため、それらの事柄はより大きな割合を占めるようになりました。複数回繰り返してこれを続けると、必ずしもマイクロ最適化を行うことなく大幅な高速化を実現できます。

そのような経験の後、新しいプログラミングの問題に取り組むと、そのような非効率性に最初につながる設計アプローチを認識するようになります。私の経験では、データ構造の過剰設計、正規化されていないデータ構造、通知への大きな依存などから来ています。


120

マイクロ最適化は、数字がそうである場合にのみ重要です。

クライアントまたはユーザーにとってパフォーマンスがまったく問題である場合、開発対象の要件にはパフォーマンスデータの仕様が必要です。ソフトウェアを開発しているときに、これらの要件に対してシステムのパフォーマンスをテストする必要があります。パフォーマンス要件を満たしていない場合、コードベースのプロファイルを作成し、パフォーマンス要件を満たすために必要に応じて最適化する必要があります。最低限必要なパフォーマンスの範囲内になったら、特にコードの可読性と保守性を損なう場合は、システムからパフォーマンスを絞り出す必要はありません(私の経験では、高度に最適化されたコードは読みにくく、保守可能ですが、常にではありません)。システムの他の品質属性を低下させることなく、パフォーマンスをさらに向上させることができる場合、

ただし、パフォーマンスが最も重要な場合があります。私は主にリアルタイムシステムと組み込みシステムを考えています。リアルタイムシステムでは、操作の順序を変更すると、適切な操作に必要なハードデッドラインの達成に大きな影響を与える可能性があり、計算結果にも影響を与える可能性があります。組み込みシステムでは、通常、メモリ、CPU電力、および電力(バッテリー電力など)が制限されているため、バイナリのサイズを減らし、計算数を減らしてシステム寿命を最大化する必要があります。


一方、遅い関数と速い関数の使用に問題がある場合、遅い関数を使用する理由はありません-issetの場合のように。
マヴリック

7
@Mavrikそれは本当です。XとYの2つの関数があり、YがXよりも速い場合(少なくとも特定の条件では)、コードが読み取り可能で保守しやすい場合、Yを使用しない理由はありません。ただし、Yがわからず、Xの代わりにYを使用するようにコードをリファクタリングする必要があり、(そのコードセグメントの)パフォーマンスが問題にならない場合、その変更を行う理由はありません。パフォーマンス、時間、コスト、労力、可読性/保守性などのトレードオフがすべてです。
トーマスオーエンズ

2
私は心から同意します。微最適化に関してはこの点を強調したかっただけです。読みやすさや時間の面で費用がかからない場合は、それを実行してください。そうでなければ、しません。
マヴリック

+1の高度に最適化されたコードは可読性が低く、保守も容易ではありませんが...
ボズ

パフォーマンスが重要な場合:(1)ゲーム。(2)大量のデータ。(3)トラフィックの多いWebサイト。(4)非常に複雑なUIの応答性。(5)ウイルスチェックのようにバックグラウンドで実行されるはずのサービス。(6)ファイナンス; (7)スマートフォン; 等々。RTSや組み込みシステムなどの難解なケースに限定されることはほとんどありません。
レックスカー

103

誰かが最適化について尋ねるたびに、マイケル・A・ジャクソンからの引用を思い出します

プログラム最適化の最初のルール:しないでください。

プログラム最適化の2番目のルール(専門家のみ!):まだやらないでください

ウィキペディアからの引用は英国英語用に修正されました。* 8 ')

2番目のルールで暗黙的に行われているのは、コードのプロファイルを作成し、違いを生むものの最適化だけに費やすことです。

アセンブリでプログラミングするとき、あなたの父親の主張は正しかった。しかし、それは最近のほとんどの人がプログラムするよりもはるかに金属に近いものです。今日はさえしようと、あなたのコードを実行することになります(プロファイリングせずに)自分自身を最適化するために、低速の一般的な方法は、近代的で最適化される可能性が高いので、あなたは、何かもっと一般的な方法で行わたい場合よりもJITのコンパイラ。

Cでも、コンパイラよりもコードのセクションを最適化する方法について詳しく知るには、最適化がかなり上手でなければなりません。

Ulrich Drepperが彼の優れた論文「すべてのプログラマーがメモリについて知っておくべきこと」で述べていることの多くをよく知らない場合、おそらくあなたは自分自身を最適化しようとしても負けているでしょう。しかし、論文のタイトルとは反対に(実際にはすべてのコンピューター科学者が浮動小数点演算について知っておくべき素晴らしいDavid Goldbergのオマージュです)、このレベルの理解がなくても、必ずしも優れたプログラマーであるとは限りません。プログラマー。

isset()strlen()PHP

私はPHPを知らないので、何isset()をするつもりなのか明確ではありません。コンテキストから推測することはできますが、これは、初心者のPHPプログラマーにとっても同様に不明瞭であり、経験豊富なプログラマーをダブルテイクさせることさえあることを意味します。これは、保守を悪夢にする言語の慣用的な使用法の一種です。

それだけでなく、isset()現在より効率的であるという理由だけで、常により効率的であるという保証はありません。最適化は、来年または10年後には最適化されない可能性があります。CPU、システム、コンパイラーは時間の経過とともに改善および変更されます。PHPのパフォーマンスにstrlen()問題がある場合、PHPが将来変更される可能性があるため、コードを再度最適化するためにisset()の最適化をすべて削除する必要がある場合があります。

すべての最適化は、将来の最適化に反する可能性があるため、最小限に抑えるために、コードのにおいの可能性があると考えてください。

個人的な経験からの例

そのような例として抗最適化、私は一度、フォームのコードでいっぱいの巨大なコードベースをサニタイズしていたif x==0 z=0 else z=x*y誰かが浮動小数点乗算がされたことを前提として作られていたので、いつもの枝よりも高価になるだろうし。元のターゲットアーキテクチャでは、この最適化によりコードの実行速度が1桁速くなりましたが、時間が変わります。

高度にパイプライン化された最新のCPUでこのコードを使用しようとすると、パフォーマンスが恐ろしく悪くなりました。これらのステートメントはすべてパイプラインフラッシュを引き起こします。これらのコード行をすべて単純化z=x*yして、新しいアーキテクチャでプログラムを1桁高速に実行し、最適化対策によって失われたパフォーマンスを復元します。

通常、今日最適化する必要がある問題は、20年または10年前に最適化する必要がある問題とは大きく異なります。

その後、我々は今、我々はCPUレベルでのパイプラインのフラッシュ、分岐予測ミスとキャッシュミスを心配されやすい、クロックサイクルあたり最大仕事をして心配したが、ロックおよびプロセス間通信にはなってきてずっと私たちは、マルチために移動すると、より大きなプロセスおよびマルチプロセッサアーキテクチャ。Drepperの論文は、これらの問題の多くを理解するのに本当に役立ちます。


3
パイプラインフラッシュとキャッシュミスは避けたいものです:Dひどいコストがかかります。しかし、それらを何度も何度も実行するコードの部分でのみ。
deadalnix

7
私が付け加えたいことの1つは、コンパイラーが長い道のりを歩んできたことで、多くのことを最適化できることです。知る限り、彼らはトリッキーなものよりもきれいで読みやすいコードを最適化する方が良い。
Becuzz

3
+1は、時間を無駄にするマイクロ最適化の実際の例を提供し、マイケルジャクソンがプログラマーであることを明らかにしたためです。
ボズ

1
+1例の場合。簡単な変換をコンパイラーに任せる理由を完全に示しています。
back2dos

1
@Rex Kerr>この例では、コストは分岐によるものであり、CPUのパイプラインがフラッシュします。浮動小数点乗算も高価です。より高価なものは、コードを実行するCPUのFPUとパイプラインの長さに大きく依存します。このコードが、現在のCPUよりもパイプラインが短く、FPUの効率が低い古いCPUで高速に実行されたことは驚くことではありません。
-deadalnix

84
  1. クリーンで簡潔、シンプルで自明なコードを記述してください。
  2. パフォーマンステストを行って、ボトルネックを特定します。
  3. クリティカルセクションを最適化します。

経験則として、コードの95%が5%の時間実行されます。コードをプロファイリング/ベンチマークし、95%の時間で実行される5%を確認する前に最適化する意味はありません。

すべてのバカがマイクロ最適化を行うことができ、適切なコンパイラ/ランタイムがこれを行います。
適切なコードの最適化は簡単です。最適化されたコードを記述し、その後それを改善しようとするのは、せいぜい退屈で、最悪の場合は持続不可能です。

あなたがいる場合真剣に、パフォーマンスの世話、そしてパフォーマンスの重要なコードのためのPHPを使用しないでください。ボトルネックを見つけて、C拡張機能で書き換えます。難読化のポイントを超えてPHPコードを微最適化しても、ほとんど同じ速度にはなりません。

個人的には、プログラミングを始めたとき、マイクロ最適化をするのが好きでした。明らかだからです。すぐに報われるからです。あなたは重要な決定を下す必要がないからです。先延ばしの完璧な手段です。これにより、ソフトウェア開発の本当に重要な部分であるスケーラブル、柔軟、拡張可能、堅牢なシステムの設計から逃げることができます。


2
私にとっての最良の答えは、Bugzilla Developer's Guideで顕著に見つかりました。 :問題が実際に存在することを知る前に解決しないでください(実際の詳細なテストによって)コードが遅いことがわからない場合は、コードを「高速化」することを心配しないでください。最適化-多くのプログラマーは、誰も経験したことのない問題を常に解決しています。それをしないでください。」bugzilla.org/docs/developer.html#general
マルコ

7
私は一般的に同意します-1 行を除いて、私は「すべてのばか彼らがマイクロ最適化できると思う」と主張します...;)
ニム

@Nim:ポイントを取得;)
back2dos

26

私はあなたの父親に同意します:「コーダーがマイクロレベルでもコードのパフォーマンスを考慮しないなら、彼らは良いプログラマーではありません。」キーは「パフォーマンスを考慮する」ことです。これは、「すべてのステップでマイクロ最適化を行う」と同等ではありません。

私は他のコメントのほとんどに同意します-Cプログラムを高速化するために使用されたものは今日はそうではないかもしれません-しかし、考慮すべき他の深刻なことがあります:CまたはC ++を使用する必要がありますか?単純にオーバーロードされた演算子を持つクラスは、それらを頻繁に使用するとパフォーマンスが低下する可能性があります。それは問題ですか?それはあなたのアプリケーションに依存しますが、もしあなたがそれを考慮しなければ、あなたはあまり良いプログラマーではありません。一部の人々は約2ミリ秒の間それを検討し、それを却下するかもしれませんが、私はあまりにも多くが文字通りそれを考慮すらしないと思います。

現実には、最適化により、コードが読みにくくなる可能性があります。コードの記述には時間がかかります。コードは、少し速くなり、桁違いに速くなります(まれです)。顧客はおそらく違いを知らないでしょう。

もう1つの現実は、人々がコードを再利用することを好み、最終的にコードを記述した場所とはまったく異なる場合があるということです。突然人々は気にするかもしれません。

例として、Angry BirdsのようなものをPCやゲーム機で書いたとしましょう。物理システムとグラフィックシステムの最適化を無視しました-最近は2.5 GHzデュアルコアが基本的に最小であり、ゲームが十分に機能するためです。その後、スマートフォンが登場し、それを移植したいと思います。ああ、600 MHz ARMコアですか?

Webサイトを考えてみてください-週末にHot or Notのようなものが一緒に投げられます。便利なデータベースを使用し、迅速な開発を念頭にすべてを作成し、友人にURLをメールで送信して起動します。3か月後、サーバーは過負荷で死にかけ、スケールアップのためにできることは何もありません。それは常に起こります。最大のWebサイトには、数百キロワットまたはメガワット単位で測定される電力料金があります。考えてみてください、コードの最適化によって節約できるメガワットがあります。

あなたの父親が言ったように、少なくともそれを考慮しなければなりません。ほとんどの人は、テーブルのパフォーマンスがどれほどあるかさえ知らず、「時期尚早な最適化」と「やらない」についての簡単なヒントでそれを詳しく説明します。これらは良いプログラマーではありません。

これは、これらのサイトで一般的な意見ではありません。さようなら評価ポイント....


3
確かに、(頭の後ろで)それを考慮し、それが価値があると示されない限り、通常それを拒否する必要があります。通常、最適化によりコードの可読性が低下し、コード化と保守にかかる時間が10倍ほど長くなる可能性があることを考慮する必要があります。プログラムがCPUを集中的に使用しない場合、多くの場合必要ありません。コンパイラは通常、最適化が自分よりもはるかに優れており、最適化の多くが実際にパフォーマンスを損なうことを認識してください。最適化とプロファイルのテストに時間をかける価値がない場合は、最適化に時間をかける価値はありません。
ジンボブ博士11

3
あなたのAngry Birdsの例は、時期尚早に最適化すべきではない理由を正確に示しています。デスクトップからコンソール、モバイルデバイスへの移植では、(少なくとも)3つの非常に異なるタイプのハードウェアを扱っており、あるハードウェアの最適化は別のハードウェアの助けではなく傷つく可能性があります。さらに悪いことに、最適化によってコードが理解しにくくなり、移植が難しくなります。確かに、最初から効率的なアルゴリズムを選択しますが、実際のデータが各プラットフォームのどこに問題があるのか​​を示すとき、パフォーマンスチューニングフェーズの微最適化を保存します。
カレブ

@Caleb:Angry Birdsの例は、特定のハードウェアに最適化しない理由を示しています。また、より一般的な「Cレベル」の最適化を行うことなく、アプリ全体をビルドしてから焼き付ける方法も示しています。実際には火傷していませんが、元の意図を超えて問題を抱えています。
-phkahler

25

まず、ケースを見てみましょう:PHP

  • PHPは、これらの「マイクロ最適化」を心配する必要のある種類の言語ではありません(その性質とアプリケーションのメインドメインの両方のため)。PHPコードは、主にオペコードキャッシングで最適化されています。
  • PHPで書かれたプログラムはCPUバウンドではなく、ほとんどがI / Oバウンドであるため、これらの最適化はあなたの時間の価値はありません。
  • 最適化する必要があるものはすべて、C拡張にスナックし、PHPランタイムに動的にロードする必要があります。
  • ご覧のとおり、PHPでコードを微最適化してもインセンティブは得られませんが、PHPコードをより読みやすく保守しやすくすることに時間を費やした場合、より多くの利益が得られます。

一般に、

PythonRubyなどの動的言語でコードを最適化するのに "TOOOOO"を費やす時間はあまりありません。CPUを集中的に使用する数値計算タスク向けに設計されていないためです。彼らは、現実世界の状況を精巧な方法(読みやすく維持しやすい)でモデル化すること(表現力と呼ばれる)が速度よりも重要であるさまざまなクラスの問題を解決します。速度が最大の関心事である場合、そもそも動的ではありません。

コンパイルされたプログラム(C ++、Java)では、最適化がより重要です。しかし、そこにも、最初にあなたが書いているプログラムの性質/ドメイン/目的を見なければなりません。また、最適化の時間とその最適化による利益を慎重に比較検討する必要があります。さらに最適化が必要な場合は、一歩下に行くことを検討することもできます。アセンブラーでコードのこれらの部分をコーディングします。

したがって、元の質問に答えるには、「コーディングの際にマイクロ最適化は重要ですか?」-答えは-それは依存します-

  • あなたはどのようなことをしていますか:アプリケーションドメイン、複雑さ?
  • プログラムにとってマイクロ秒の速度向上は本当に重要ですか?
  • どのような最適化が最も効果的ですか?常にコードの最適化であるとは限りませんが、外部的なものです。
  • マイクロ最適化に投資する時間からどれだけの「良さ」(速度の面で)を獲得していますか?
  • ハードウェア、RAM、プロセッサの変更、コードの並列実行、または分散システム上で、他の方法でより良い速度を達成できますか?

マイクロ最適化(そのためのコード最適化)に時間がかかるだけでなく、コードの自然な可読性を「ゆがめる」ため、メンテナンスが重くなります。常に最後の手段と考えてください。個々のコードファイルを最適化するよりも優れたハードウェアとアーキテクチャを採用することにより、常にアプリケーション全体を最適化してください。


18

マイクロ最適化とは多くの答えがあるようです

すべてのトレードオフ-パフォーマンス、時間、コスト、労力、読みやすさ/保守性など。

しかし、読みやすさの影響がない最適化がいくつかあることは知っています。楽しみのためにそれらを実行したいだけです。私はいくつかの学校の課題(すべて速度ベース)で、次のような条件付きステートメントを作成する際にマイクロ最適化を考慮することは常に良いことだと考えました。

if (counter < X && shouldDoThis()) // shouldDoThis() is an expensive function

いつもよりいいです

if (shouldDoThis() && counter < X ) 

そのようにコードを「高速化」する方法はかなりありますが、その差は通常は無視できます(常にではありません)が、そのように記述した方が良いと感じます。

これを実際の最適化とみなす人がいるかどうかはわかりませんが、プログラマーはコードを書くときにこれらのことを知って考慮すべきだと思います。


2
この特定のケースでは重要ではない場合があります。しかし、私はそれだと思う非常にそれはときように、これらのような最適化を認識することができることは重要でない問題、あなたは事後プロファイリングおよび最適化不要な時間を費やす必要はありません。
-tskuzzy

4
これは非常に危険な例です。最適化は、必要があります決して動作を変更しません。それcheap() && expensive()が最適化であることを示唆することでさえ、expensive () && cheap()人々はそれが作成する重要なセマンティックな変更に関係なく盲目的に一方を他方に置き換えるように誘います(&&短絡演算子がある言語で)。
マークブース

5
関数に副作用がない場合、それらは同等であり、より高速です。副作用がある場合、そもそもこのようなコードを書くべきではありません。私はこれが習慣から行われるべきだとさえ言うでしょう-それが実際に振る舞いを変えない限り。
-phkahler

3
@MarkBoothここでphkahlerに同意する必要があります。これらの関数には副作用はありません!ifステートメント内の条件の順序は、プログラムの結果に影響を与えてはなりません。私の例はif (x<100 && isPrime(x))、よりわかりやすくするために、のように書く方が良いでしょう。
-zidarsk8

1
@ zidarsk8- 最適化によって実行速度以外が変更された場合、それは最適化ではありません。プログラマとして、私たちはしばしば実用的である必要があり、それは時には短絡演算子で使用されるすべての関数が純粋であることを保証できないことを意味します-特にコードが制御できないサードパーティのライブラリを呼び出す場合。そのような状況では、経験の浅いプログラマーが最適化の名においてバグを導入することを奨励されないように注意する必要があります。
マークブース

11

私のキャリアの早い段階で、「微最適化しないでください」などの包括的な声明は多くの混乱をもたらしました。すべてが状況です。したがって、人々が「これを行う」よりも「ベストプラクティス」と言う理由。

すべての状況を考慮すると、「ベストプラクティス」が一番の選択です。たとえば、LINQEntity Frameworkは、インラインSQLの代わりに使用する必要があります。私の会社では、SQL Server 2000使用しています。SQL Server 2000はEntity Frameworkをサポートしていません。ベストプラクティスの要件:

  • SQL Serverの新しいバージョンを購入するというアイデアで上司を売りました。これは数千ドルを意味します。
  • 開発者に新しいテクノロジーを学ぶというアイデアを売り込む。

私は経験からこれが起こらないことを知っています。ですから、やめたり、ストレスを感じたり、ベストプラクティスに従わなかったりする可能性があります。

全体的な結果に影響を及ぼす決定の背後には、政治的、技術的、および金銭的な考慮事項があります。決定を下す際にはこの事実を覚えて、賢明な戦いを選択してください。

すべてのために、季節、天国の下であらゆる活動のための時間があります。


1
ところで、インラインSQLに代わるmicro-ORMとしてDapperを使用できます。
ダン

2
LINQ and Entity Framework should be used in lieu of inline SQL-何かを最適化するために実際にインラインSQLが必要になるまで。EFが生成するSQLは常に最適とは限りません。
ロバートハーベイ

1
FWIW、あなたの上司は、SQLの2K8(または任意の他、現在でもよい)のライセンス費用を心配しているならば、あなたはポイントアウトする必要があり、それは今後アップすることがEOLに十分な年齢だと非常にすぐに(まだない場合)
ウォーレン・

@warren-一部の企業はそのようなことを考慮していません。一部の人にとっては、それがまだ「機能する」場合、アップグレードしません。仕事とは、サーバーがまだ実行されているという意味です。すでにEFのサポートが不足しています。それだけではお金を使うように説得するのに十分ではありません。
P.Brian.Mackey

1
EFをSQL 2000で使用できます。デザイナーは機能しませんが、実際のエンティティフレームワークはSQL 2000をサポートします。デザイナーの制限を回避するには、同じスキーマを使用してSQL 2008 Expressでローカルデータベースを作成します。 sql 2000データベースとして、デザイナーを指定してすべてのクラスを生成し、.edmxファイルに移動してターゲットデータベースバージョンを2000に変更し、sql server 2000データベースで接続文字列を指定します。最善の解決策ではありませんが、アップグレードできない場合は機能します。
ニール

8

これは常にトレードオフです。

まず、コンピュータ業界は最後にお金についてです。開発者としてあなたがしなければならないことは、顧客のために価値を生み出すことです。そうすればお金を得ることができます(これは単純化しすぎですが、ここで重要な点です)。

開発者の時間にはお金がかかります。機械の動力にもお金がかかります。通常、この2番目のコストは最初のコストよりもはるかに低くなります。したがって、これは読み取り可能なコードと保守可能なコードを持つための資本であるため、開発者はほとんどの時間を価値の提供に費やすことができます。

場合によっては、マイクロ最適化が重要になることがあります。ただし、通常は、読み取りにくいコードまたは拡張性の低いコードを使用します(これはリンクされた例の場合ではありませんが、一般的にはそうです)。これは、ある時点で開発者の費用がかかります。今回は機械の動力よりも高価ですが、これは無駄です。

第二に、大規模なプロジェクトでのマイクロ最適化により、メンテナンスや進化がますます難しくなります。それに伴う問題は、進化するとき、他の最適化が不可能になる可能性があることです。進化するアプリケーションを使用すると、通常、それらの最適化を行わなかった場合よりも遅いソリューションになります。

第三に、アルゴリズムの複雑さは一般に、データセットが大きくなった場合に行うことができたあらゆる微小最適化を克服するため、最適化はしばしば重要ではありません。残念なことに、マイクロ最適化によりコードの維持/進化が難しくなるため、それらの最適化を行うのが難しくなる可能性があります。

いつか、この最適化に価値があります(ビデオゲームや航空機の自動操縦など、遅延が重要なプログラムについて考えてください)。しかし、これは実証されなければなりません。通常、プログラムはほとんどの時間をコードの限られた部分に費やします。どのような最適化を行っても、ボトルネックを特定してこの部分で作業することなく、プログラムを非常に高速化することはありません。

あなたが質問したところ、実際のプログラムで問題のベンチマークを行っていないことがわかりました。この場合、あなたはトリックを行うことができ、それがより速いかどうか気づいたでしょう。あなたは問題を抱える前にそれを尋ねていました。これが問題のある場所です。最適化の問題を間違った方法で処理していました。

メンテナンスと進化は通常、マイクロ最適化よりも価値があるため、実行する前に適切なインターフェイスを用意してください。次に、プログラムの一部が互いに抽象的である場合は、全体を台無しにすることなく、一部を最適化できます。これには、信頼できるようにインターフェースが十分に長く実行されている必要があります。


「常にトレードオフがあります」。確かに、プログラムがトレードオフ曲線上にある場合、 1つの変数を減らすと他の変数が増えます。私の経験では、ほとんどのプログラムはトレードオフ曲線に近くなく、両方の変数を減らす余地が十分にあります。
マイクダンラベイ

+1のメンテナンスと進化は、マイクロ最適化よりも価値があります。コンピューター業界は単なるお金以上のものだと確信していますが?たとえば、オープンソース、教育、イノベーション、ガバナンス、コミュニティなど。お金はその根源にあると確信していますが、それはほとんどのものに当てはまります。
ボズ

@Boz kay>これは部分的に当てはまります。最初に、あなたの上司と顧客はそれらについてほとんど知らないので、お金を気にします。いくつかのオープンソースツールを宣伝したい場合、会社のブランドをどのように改善するか、開発コストをどのように削減するかを伝える必要があります。さらに、開発者を幸せにすることは、あなたの会社で優れた開発者を獲得する方法です。優れた開発者はお金を稼ぎます(大部分は品質と革新を投げかけます)。最後に、お金が鍵です。そして、私は私のLinuxコンピューターから素晴らしいソフトウェアのサポーターになると書いています。教育についても同じことが言えます。
deadalnix

8

パフォーマンスは機能です

Jeff Atwoodの記事は、高性能Webサイトの構築とその重要性に関する素晴らしい記事です...

とはいえ、必要になるまでマイクロ最適化に焦点を合わせないでください。実行できる費用対効果の高い最適化があります。コードではなく、アーキテクチャに注目してください。私が見たほとんどのWebサイトには、パフォーマンスが低下するだけでなく、深く根付いていて修正が難しい高レベルの問題(不要なWebサービスレイヤー、貧弱なデータベースデザイン、過度に複雑なアーキテクチャ)があります。

Webサイトを構築するとき、クライアント側のコードとデータベースロジックは、サーバー側のコードよりもパフォーマンスの問題を引き起こす可能性がはるかに高くなります。ただし、他のことと同様に、パフォーマンスの問題がある場合は、コードのプロファイルを作成しておくと、コードを早期に見つけることができます。


7

開発者の時間はコンピューターの時間よりも費用がかかります。それは通常、最適化するものです。しかし:

  • マイクロ最適化とアルゴリズムの複雑さには違いがあります。適切なアルゴリズムを使用していると確信するのに十分な時間を費やしてください。
  • 正しい質問をしていることを確認してください。select (select count(*) from foo) >= 1これはとは異なりますselect exists(select 1 from foo)
  • 一部の言語イディオムは、単に高速であるという理由だけで人気があります。言語の流なユーザーのほとんどはそれらに精通しているため、それらを使用しても構いません。(あなたの例は良い例です)。

7

何を最適化したいですか?

  • ソフトウェアのパフォーマンス?
  • 信頼性?
  • プログラマの生産性は?
  • 顧客満足?
  • 電力効率?
  • 保守性?
  • 市場投入までの時間は?
  • コスト?

「最適化」とは、常にコードを可能な限り高速に実行することを意味するわけではありません。絶対的な最速の方法を見つけることが重要な場合もありますが、ほとんどのコードではそれほど一般的ではありません。ユーザーが50マイクロ秒と100マイクロ秒の違いに気付かない場合、たまにしか実行されないコードの2つに実質的に違いはありません。以下に例を示します。

ユーザーの入力の長さと、2つのルーチンのいずれかが2つの連続したキーストローク間の時間よりもはるかに短いと判断するのにかかる時間の表示を継続的に更新する必要がある場合、どのルーチンが本当に重要ではありませんあなたが使う。一方、10億個の文字列の長さを決定する必要がある場合は、おそらく、異なるルーチン間のパフォーマンスの違いに細心の注意を払う必要があります。最初のケースでは、理解して検証しやすいコードを書くことを好むかもしれません。2番目のケースでは、読みやすさと速度を犠牲にすることができます。

いずれにせよ、コードを最適化する場合は、変更の前後にコードをプロファイリングする必要があります。最近のプログラムは非常に複雑なため、ボトルネックがどこにあるのかを判断するのが難しい場合があります。プロファイリングは、適切なコードを最適化し行った最適化が実際に機能したことを示すのに役立ちます。

父親がいつ退職したのか、どのようなプログラミングをしたのかは言わなかったが、彼の反応は驚くことではない。歴史的に、メモリ、二次ストレージ、および計算時間はすべて高価であり、時には非常に高価でした。最近では、これらのすべてがプログラマーの時間に比べて非常に安くなっています。同時に、プロセッサーとコンパイラーは、プログラマーが決して一致させることのできない方法でコードを最適化できるようになりました。プログラマーが少しのトリックを使って、ここでいくつかの機械語命令を焼き払う日々はほとんどなくなりました。


1
+1言うまでもなく、ここ数年で、モバイルデバイスは再びコードの最適化に大きく依存するようになりました。最適化されたコードを作成していないか、少なくともCPUを集中的に使用するアプリをモバイルデバイスでスムーズに実行するのに苦労している人はいます。
スタイラー

可能な最適化のリストと非常によく似ています。彼はアセンブリ/フォートランを使用しました
Boz

@Styler:モバイルデバイスには、GBのメモリを搭載したクアッドコアCPUが搭載されるまでそう長くはかかりません。すでにデュアルコアのスマートフォンがあります。
ライライアン

@リーライアン:はい、これは本当ですが、ほとんどの先駆者と同様に、彼らは木製のボートで旅行しなければなりませんでした;)
スタイラー

7

コードの作成中にマイクロ最適化することは重要ではありません。プロファイラーの助けを借りて最適化を行い、重要なコードを最適化する必要があります。

ただし、プログラマー、コードの作成中に明らかに愚かなことをしないようにしてください。

たとえば、ループ内で繰り返し高価な操作をしないでください。ループ外の変数に値を保存し、それを使用します。レベルを上げて比較を行い、整数または関数参照または派生クラスにすることができる場合、頻繁に呼び出される関数で文字列比較や正規表現のようなことを何度もしないでください。

これらのことは経験豊富なプログラマーにとって覚えやすく、ほとんどの場合コードの品質を向上させます。


私は自分の質問の編集をより明確にする必要があることに気付き、同じことを本当に言っていました-それを更新しました。
ボズ

7

何を最適化するかを決めるときは、常にアムダールの法則を思い出してください。正確な数学についてはリンクをご覧ください。覚えておくべき簡潔な声明は次のとおりです。

プログラムの一部が実行時間の10%を占め、その部分を2倍の速度で実行するように最適化すると、プログラム全体の速度は5%しか向上しません。

これが、総実行時間の数パーセント以上を占めないプログラムの部分を最適化する価値はないと人々がいつも言う理由です。しかし、それはより一般的な原則の特別な場合です。アムダールの法則によれば、プログラム全体を2倍の速度で実行する必要がある場合は、すべてのピースを平均50%スピードアップする必要があります。20ギガバイトのデータを処理する必要がある場合、ディスクから20ギガバイトを読み取るのにかかる時間よりも速くする方法は2つしかありません:より高速なディスクを取得するか、データを小さくします。

それで、アムダールの法則は、マイクロ最適化について何と言っていますか?彼らが全面的に適用する場合、彼らはおそらく価値があると言います。プログラム内のすべての関数の実行時間を1%削減できる場合、おめでとうございます!プログラムを1パーセント高速化しました。それはやりがいがありましたか?まあ、コンパイラーとして私はそれを行った最適化を見つけて喜んでいるでしょうが、あなたがそれを手でやっているなら、もっと大きなものを探してください。


1
アムダールの引用には+1ですが、「プログラム全体を2倍速く実行するには、すべてのピースを高速化する必要があります」とは同意しません。実際に「ピース」をスピードアップしないと言います。むしろ、不要な作業を見つけて排除します。プログラムがおもちゃよりも大きい場合、特に関数呼び出し。パフォーマンスに関する一般的な考え方の多くは、コールツリーの不要なブランチ全体(単一の命令である場合もある)を見つけて、それらを切り落とすことの重要性を完全に無視しているようです。
マイクダンラベイ

悪魔は「平均的」という言葉の中にあります。数学的には、プログラムを50%高速化するには、すべてのピースを平均 50%高速化する必要があります。これで、実行時間の75%を要するジョブと25%を要するジョブにプログラムを分割し、前者を3倍高速化できれば、後者のジョブに何もしなくても全体で50%を得ることができます。しかし、はるかに一般的なケースは、それぞれが実行時間の5%未満を要する「ジョブ」が多数あることです。そして、それらの多くを高速化するか、取り除く必要があります。
zwol

もっと一般的なケースがあると思います。50%の時間がかかる「ジョブ」がありますが、実際には必要ないので、完全に削除し、その分だけ全体の時間を短縮してから繰り返します。私はこれを受け入れるのが難しいことを知っています-プログラムは(後から見れば)まったく不要なことをするのにかなりの時間を費やすことができるということです。しかし、ここに私の標準的な例があります。
マイクダンラベイ

6

開発のどの段階にあるかによって異なります。最初に何かを書き始めたとき、マイクロ最適化は、マイクロ最適化を使用するよりも優れたアルゴリズムを使用することでパフォーマンスが向上するため、考慮すべきではありません。また、時間に敏感なアプリケーションは、一般的なビジネスアプリケーションよりも、マイクロ最適化の考慮事項からより多くの利点が得られるため、開発しているものを検討してください。

ソフトウェアをテストおよび拡張している場合、マイクロ最適化によりコードが読みにくくなり、修正する必要のある他の修正とともに修正する必要のある独自のバグのセットを導入する傾向があります。

あなたが実際に遅いコードについてユーザーから苦情を受け取っているなら、彼らは検討する価値があるかもしれませんが、他のすべてが解決されている場合にのみ、すなわち:

  • コードはうまく書かれていますか?
  • アプリケーションは問題なくデータにアクセスできますか?
  • より良いアルゴリズムを使用できますか?

これらの質問にすべて回答してもパフォーマンスの問題が解決しない場合は、コードでマイクロ最適化を使用し始めるかもしれませんが、他の変更(つまり、より良いコード、より良いアルゴリズムなど)があなたを正すことになるでしょうマイクロ最適化よりもパフォーマンスが向上します。


5

実行速度は、プログラムの品質に寄与する多くの要因の1つです。多くの場合、速度は可読性/保守性と逆相関します。ほとんどすべての場合、コードを維持できるように、コードは人間が読み取れる必要があります。可読性が損なわれる可能性があるのは、速度が不可欠な要件である場合のみです。完全な可読性/保守性が許容するよりも高速にコードを作成するという要件はほとんど適用されませんが、そうなる場合があります。覚えておくべき主なことは、マイクロ最適化されたコードはしばしばハッキングコードであるため、どこかに定義された要件がない限り、ほとんど常に問題を解決する間違った方法です。たとえば、ユーザーはCRUD操作の0.5秒と1秒の実行時間の違いにほとんど気付かないでしょう。そのため、その.5秒に到達するためにassembly-interop-hackfestに進む必要はありません。はい、ヘリコプターを使って仕事をすることができ、10倍速くなりますが、価格とヘリコプターのほうがはるかに飛行が難しいという事実のためではありません。コードを不必要に微最適化する場合、これがまさにあなたがしていることです。不必要な目標を達成するために不必要な複雑さとコストを追加します。


5

制約にぶつかった場合、マイクロ最適化は重要です。気になるのは、メモリ、スループット、待ち時間、または電力消費です。これらはシステムレベルの特性であることに注意してください。すべての機能をあらゆる方法で最適化する必要はありません(できません)。

組み込みシステムは、制約がより簡単にヒットするため、マイクロ最適化が必要になる可能性が高くなります。ただし、そこまでマイクロ最適化を行っても、これまでのところは得られません。悪いデザインから抜け出す方法を微最適化することはできません。システムの優れた設計に関するポイントは、システム全体について推論できることです。マイクロ最適化が必要なコンポーネントは、システムの設計を損なわない方法で適切に公開および最適化する必要があります。

今日の小さな「組み込み」システムは、昨年のVaxenまたはPDP-11に非常に近いため、これらの問題は以前より一般的でした。現代の一般的な商用コンピューティングを行う現代の汎用システムでは、マイクロ最適化はまれです。これはおそらくあなたの父親が彼の立場をとる理由の一部です。

ただし、ナノ秒、ミリ秒、秒、時間のどれを扱っているかは関係ありません。問題は同じです。それらは、システムのコンテキストと達成しようとしているものの中で評価する必要があります。

これは、マイクロ最適化が必要な場合のスタックオーバーフローに関する最近の質問からの例です組み込みシステム用のオープンソースビデオエンコーダーです


4

マイクロ最適化の最大の問題は、メンテナンスが難しいコードを書くことにつながることです。

別の問題は、コンピューターの構成によっては、「最適化」を行わない場合よりも、マイクロ最適化のパフォーマンスが最悪になる場合があります。

多くのマイクロ最適化を行うと、本当に重要ではない何かと戦うのに多くの時間を消費します。

より良いアプローチは、よりクリーンなコードを作成し、保守を容易にすることです。パフォーマンスの問題が発生した場合は、プロファイルを実行して、実際にコードが遅くなっているものを見つけます。そして、本当に何が悪いのかを正確に知ることで、それを修正することができます。

マイクロ最適化を行わないことが愚かなコードを書く理由になると言っているのではありません。


4

ミリ秒について心配し始めたら、PHPを放棄し、代わりにCまたはアセンブリを使用することを検討する必要があります。私はこれをやりたいとは思わないが、そのような数字について議論し、スクリプト言語を使用することは意味をなさない。とにかく頻繁にこのコマンドでコードを繰り返しますか?

環境要因はここでは問題ではありません。それらのサーバーはとにかく年中無休で実行され、実際に何かを処理する場合は、それが本当に長時間実行されるタスクである場合にのみ重要です。

おそらくあなたのオフィスの光と私たち全員が質問と回答を入力している間にコンピューターが使用したエネルギーは、アプリケーションに合理的に適用できるあらゆる種類のマイクロ最適化よりもはるかに多くのエネルギーを消費します。


+1消灯または質問に答えない。
ボズ

4

タスクに最適なシンプルなアルゴリズムを選択する必要があります。シンプルにする必要があるのは、コードを読みやすくするためです。それが最良である必要がある理由は、悪いランタイム特性で開始することを避けるためです。大規模なデータセットが存在することがわかっている場合、BubbleSortをやみくもに選択しないでください。ただし、10個の要素がときどきソートされる場合は問題ありません。

次に、プロファイリングの数値が、最適な単純なアルゴリズムの選択が十分ではないことを示している場合、最適化を開始できます(通常は読みやすさの代償として)。


BubbleSortは、最終目的地からそれほど離れていないわずかな漂遊要素だけでデータがほぼソートされている場合、実際にはクイックソートまたはマージソートよりも優れています。ただし、他のすべてのタスクについては、プログラミング言語が提供する組み込みソート機能を使用する必要があります。開始する最も簡単な方法です(ほとんどの言語の組み込み並べ替え機能は優れたパフォーマンスを発揮します)。悪いアドバイス:start out with bad runtime characteristic、悪いランタイム特性で意図的に開始しないでください。
ライライアン

@Lie、データがほぼソートされていて、バブルソートを使用できることを知っていれば、アルゴリズムを盲目的に選択しているわけではありません...また、タイプミスを指摘してくれてありがとう。

4

前にも言ったことがありますが、ここでは「早すぎる最適化がすべての悪の根源です」と言います。これは、プログラマーの心の中心にあるルールの1つでなければなりません。

ある程度までは、コードは常に現在よりも高速になります。特定のチップを念頭に置いてアセンブリを手で梱包する場合を除き、最適化によって得られるものは常にあります。ただし、すべてを行うためにアセンブリを手で梱包したくない場合は、定量的な目標を設定する必要があります。目標を達成したら、「それで十分です」と言って最適化を停止します。あなたの顔。

美しく、エレガントで、非常にパフォーマンスの高いコードは、うまくいかなければ役に立たない(そして、「働く」とは、すべての期待される入力に対して期待される出力を生成することを意味する)。したがって、常に機能するコードを作成することが最優先事項です。動作した後、パフォーマンスを評価します。不足している場合は、それを十分に改善する方法を探します。

パフォーマンスに影響を与える事前の決定が必要なことがいくつかあります。このソリューションの実装に使用する言語/ランタイムなどの非常に基本的な決定。これらの多くは、1つのメソッドと別のメソッドを呼び出すよりも桁違いにパフォーマンスに影響します。正直なところ、スクリプト言語としてのPHPは既にパフォーマンスに影響を与えていますが、C / C ++でボトムアップで構築されているスクリプトサイトは非常に少ないため、選択する可能性のある他のテクノロジ(Javaサーブレット、ASP.NETなど)。

その後、I / Oメッセージのサイズが次に大きなパフォーマンスのキラーになります。ハードディスク、シリアルポート、ネットワークパイプなどの読み書きを最適化すると、I / O操作の背後にあるアルゴリズムが効率的であっても、通常はプログラムの実行時間が大幅に改善されます。その後、アルゴリズム自体のBig-Oの複雑さを軽減します。絶対に必要な場合は、より安価なメソッド呼び出しを選択し、他の難解な決定を低レベルで行うことにより、「最適化」できます。


2
+1常に機能するコードを作成することが最優先事項です。
ボズ

2
@キース、実際にはクヌースが最初にそれを言った、そして彼はそれよりもかなり多く言った。

「機能させてから、必要なだけ高速に機能させます」、アノン。
ジョンサンダース

1
実際、宗教はすべての悪の根源ですが、私は脱線します。
トーマスエディング

4

お父さんは引退したプログラマーだと言います。メインフレームの世界で働いていたプログラマーは、パフォーマンスについて非常に心配する必要がありました。メインフレームがユーザーあたり64 KBのメモリにハードウェア制限されている米国海軍の活動を研究したことを覚えています。そのプログラミングの世界では、可能な限り小さなビットを探し出す必要があります。

現在、状況は大きく異なり、ほとんどのプログラマーは、マイクロ最適化についてそれほど心配する必要はありません。ただし、組み込みシステムのプログラマーは依然として最適であり、データベースの人々は依然として最適化されたコードを使用する必要があります。


3

コードは、それが何をするかについて完全に明確になるように書かれるべきです。その後、場合にのみあれば、それはあまりにも遅いです、戻って、それをスピードアップ。コードは、理解できるのであれば、後で高速になるようにいつでも変更できますが、幸運なことに、コードが高速であれば明確になるように変更してください。


3

次の場合に重要です。

1)誰かの人生はあなたのコードに依存します。誰かの心拍数モニターで実行するのに25msかかる関数は、おそらく悪い考えです。

私は個人的に2つのアプローチを取ります-読みやすさに影響を与えない、あなたができる微最適化があります-明らかにあなたはそれらを使いたいです。しかし、それが読みやすさに影響する場合は、控えてください-あなたはあまり利益を得ず、実際には長い時間でデバッグするのにもっと時間がかかるかもしれません。


2
あなたの例のほんのいくつかのマイナーポイント:25msかかる心拍数モニターの機能は、他の必要なタスクが必要な応答時間で発生する可能性がある限り、問題にはなりません。これには割り込みが適しています。そして、現実世界のイベントを監視して人間の消費に合わせてディスプレイを更新するだけの場合、25msの遅延はおそらく問題ではありません。
janm

3

コーディングの際にマイクロ最適化は重要ですか?

いいえ、JVM.NETのようなプラットフォームがあり、仮想マシン用にコードが記述されているため、実行を最適化しようとしてもうまくいかない場合があります。開発者のデスクトップで最適なものは必ずしもサーバーで同じではありません。ここで、これらの高レベルソフトウェアの一部がハードウェアからどれだけ離れているかを見てみましょう。考慮すべき点は、ハードウェアの多様性です。新しいモデルがおそらく1年以内に登場する場合、CPUやGPUなどの特定のチップのコードを最適化するのはどれほど現実的ですか。

ここで考慮すべきもう1つの問題は、実行速度、実行に使用されるメモリ、新機能の開発速度、コンパイルまたはデコンパイルされた形式のサーバー上のコードベースのサイズ、スケーラビリティ、保守性などの指標によって測定されるパフォーマンスです。 。?十分に広く考えれば、問題は些細なものになりますが、パフォーマンスを何らかの方法で測定できる限り、実際にそれがどれほどのものであると考えているかはわかりません。


いくつかのマイクロ最適化が機能する場合と機能しない場合があります。これらは、新機能やバグの修正など、はるかに高い優先度と見なされる可能性のある他の作業と比較して、そのような作業を実行する価値があるかどうか疑問に思う場所です。もう1つの質問は、ハードウェアまたはソフトウェアのアップグレードがこれらの最適化の一部を破壊する可能性があるかどうかです。


1
JVMや.NETなどのプラットフォームで絶対に最適化を実行できることに注意してください。これらはわずかに異なる形式を取ります。ただし、古い単純なCコンパイラと最新の高度に最適化されたコンパイラを比較した場合も同じです。ユーザーが実行できる最適化は異なって見えます。
ヨアヒムザウアー

1

良いプログラミングとマイクロ最適化には大きな違いがあると思います。

同じタスクを実行する方法が2つあり、一方が他方より高速で、両方が同じ可読性を持っている場合は、高速を使用する必要があります。常に。そして、これは良いプログラミングです。より良いアルゴリズムを使用して問題を解決しない理由はありません。そして、それを文書化することさえ簡単です:アルゴリズム名を与えると、誰でもそれをグーグルで検索し、それがどのように機能するかについての詳細を見つけることができます。

そして、優れたアルゴリズムはすでに最適化されています。彼らは高速になります。彼らは小さくなります。必要最小限のメモリを使用します。

プログラムを使用してもそのパフォーマンスが得られない場合でも、それらを微最適化することを検討できます。そして、最適化を可能にするには、言語を本当に知っている必要があります。

そして、ハードウェアにより多くのお金を費やす余地が常にあります。ハードウェアは安く、プログラマーは高価です。ハードウェアを購入できるタイミングを最適化して、時間とお金をかけすぎないでください。


1

ほとんどの場合、マイクロ最適化には価値がないため、IMHO コードの可読性はマイクロ最適化よりも重要です

ナンセンスなマイクロ最適化に関する記事:

私たちの多くがそうであるように、printをechoに、++ $ iを$ i ++に、二重引用符を単一引用符に置き換えるなど、意味のないマイクロ最適化に関するブログ記事を読むのはうんざりです。どうして?時間の99.999999%であるため、無関係です。どうして?時間の99.99%のため、APCなどのPHPアクセラレータをインストールするか、データベース列にこれらの欠落したインデックスを追加するか、ホームページにある1000個のデータベース要求を回避することをお勧めします。

実際に何かを返すので、printはもう1つのオペコードを使用します。エコーは印刷よりも速いと結論付けることができます。しかし、1つのオペコードに費用はかかりません。

WordPressの新規インストールを試みました。スクリプトはラップトップで「バスエラー」で終了する前に停止しますが、オペコードの数はすでに230万を超えていました。十分に言った。

そのため、ほとんどの場合、マイクロ最適化により数百万のうち1つの操作が節約されますが、読みやすさが低下します。


1

他の答えは金銭的に正しい。しかし、早すぎる最適化/マイクロ最適化と言語/フレームワーク構造の動作の理解を反映するパフォーマンスコードの記述を区別する必要がある別のポイントを追加します(申し訳ありませんが、最後の1つの単語を見つけることができませんでした) 。最後の1つ優れたコーディング方法であり、一般的にはそうすべきです!

説明します。不正な最適化(時期尚早/マイクロ最適化の読み取り)は、プロファイリングせずにコードのセクションを最適化して、実際にボトルネックであるかどうかを確認する場合ではありません。前提、伝聞、文書化されていない動作に基づいて最適化するときです。それが文書化されていて、どんなに小さくてもより効率的/ 論理的な方法で何かをするなら、私はそれを良い最適化と呼びます。他の人が述べているように、これらの両方には短所があり、良いビジネスを獲得する限り、ほとんどプロはありませんが、読みやすさを完全に損なうことがなければ、前者ではなく後者を行います。はい、読みやすさ/維持性は最も重要であり、それはどこに線を引くかです。

ここでは、良い最適化と悪い最適化の両方の無益さとして、他の人が指摘した点を繰り返します。

  1. 特定の問題に対する依存関係は変化する可能性があり、アプリケーションの論理セクション完了する前に最適化費やす時間は無駄です。比較的早い段階で最適化するということです。今日、あなたはList<T>アプリを持っていて、アプリを出荷するまでにそれを変更する必要がLinkedList<T>あり、今ではすべてのベンチマークは時間と労力の無駄でした。

  2. ほとんどの場合、アプリケーションの本当のボトルネック(測定可能な差として読み取られる)はコードの5%(ほとんどがSQLのもの)であり、他の95%を最適化しても顧客にメリットはありません。

  3. 通常、「技術的に」コードのパフォーマンスが向上すると、冗長性が増し、エラーが発生しやすくなり、メンテナンスが難しくなり、費やす時間が長くなり、収益が減少します。

  4. パフォーマンスを1%向上させることで全世界で節約できるカーボンフットプリントは、そのコードのデバッグと保守の際にチームが排出しなければならない温室効果ガスによって容易にeasily化されます。

特に不適切な最適化のマイナス面は次のとおりです。

  1. 多くの場合、期待するパフォーマンスが得られません。最適化がうまくいかなかった SOに関するこの質問を参照してください。実際、それは悪影響を与える可能性があります。それが文書化されていない動作の問題です。

  2. とにかくほとんどの場合、最新のコンパイラがあなたのためにそれをします。

最適化の悪い例と良い例をいくつか示します。

悪い人 -

  1. の代わりにより小さい整数型を使用しますInt32

  2. ++i 代わりに使用 i++

  3. for代わりにforeach(私が見た最悪のことは、ロジックを完全に無効にします)

  4. クローズド変数の回避

    string p;
    foreach (var item in collection)
        p = ...;
    
  5. 次のcharように、文字列の連結中に文字列の代わりに使用します。

    string me = 'i' + "me myself"; // something along that line - causes boxing
    

良い(.NETの世界から。自明であるべきです)-

  1. ダブルルックアップ

    if (Dictionary<K, V>.TryGetValue(K, out V))
        do something with V
    

    の代わりに

    if (Dictionary<K, V>.ContainsKey(K))
        do something with Dictionary<K, V>[K]
    
  2. すべて読み込む

    DirectoryInfo.EnumerateFiles();
    

    の代わりに

    DirectoryInfo.GetFiles();
    
  3. 2段階のキャスト:

    s = o as string;
    if (s != null)
        proceed
    

    の代わりに

    if (o is string)
        s = (string)o;
    
  4. 順序が関係ない場合

    if (counter < X || expensiveFunction())
    

    の代わりに

    if (expensiveFunction() || counter < X)
    
  5. ボクシング

    void M<T>(T o) //avoids boxing
    {
    
    }
    

    の代わりに

    void M(object o)
    {
    
    }
    

これらが顕著なパフォーマンス上の利点を与えるかどうか私に尋ねるなら、私はノーと言うでしょう。しかし、これらのコンストラクトの動作を理解することに基づいているため、それらを使用することをお勧めします。1つだけできるのに、なぜ2つの電話をかけるのですか?哲学的な観点から、その優れたコーディング慣行。また、1と3は厳密に言えば少し読みにくいですが、読みやすさよりも優れていますか?いいえ、あまりないので、使用します。これが重要です-読みやすさの比率に対してまともなパフォーマンスを維持します。それがそれであるとき、それはあなたが線を引く場所についてです。


1

「価値がある」には、書き込みと読み取りと保守がどれだけ簡単か、ユーザーに対して何かを著しく応答性が高く、インタラクティブにし、待機時間を短縮するなど、コンテキストが必要です。

特に最近私がソーダを飲むことはめったにないので、数ペニーを保存してソーダの缶を購入しても、それらのペニーを保存するために遠くを旅しなければならない場合、私にはあまり役に立たないでしょう。100万缶のソーダの購入で1缶あたり数ペニーを節約することは、大きな問題になる可能性があります。

一方、2人が私の隣にいて、1人が数ペニーでまったく同じものを安く提供し、もう1人がそうでないときに数ペニーを節約します。悲観化の。

私がよく「マイクロ最適化」と呼ぶ人々は、適用するのが簡単ではない場合、そのような最適化を検討する3つすべてが絶対にあるはずである場合、測定値、コンテキスト、およびユーザーエンドの議論が欠けているようです。私にとって、最近の適切なマイクロ最適化は、メモリレイアウトやアクセスパターンなどに関連しており、焦点が「マイクロ」に見えるかもしれませんが、実際にはマイクロではありません。

それほど前ではないが、24秒から25ミリ秒(約960倍高速)に操作を削減し、同じ出力(自動テストで保護)、アルゴリズムの複雑さを変更することなく、体積熱拡散スキニング、 「マイクロ最適化」(最大のものはメモリレイアウトの変更により約2秒に短縮され、残りはSIMD、VTuneでのキャッシュミスのさらなる分析、メモリレイアウトの再配置など)。

Wolfireはここでテクニックを説明し、必要な時間に苦労しました:http://blog.wolfire.com/2009/11/volumetric-heat-diffusion-skinning/

私の実装は、彼がそれを1分以内に終わらせるのに苦労していた間に、ミリ秒単位でそれを行うことができました: ここに画像の説明を入力してください

24秒から25ミリ秒に「微最適化」した後、それはワークフローの変化をもたらしました。アーティストは、リグを少し変更するたびに24秒待つことなく、30 FPSを超えるリアルタイムでリグを変更できます。そして、実際にプログレスバーやこの種のものが不要になったため、実際にソフトウェアの設計全体が変更され、すべてがインタラクティブになりました。それは、アルゴリズムの複雑さを改善することなくすべての改善が行われたという意味での「マイクロ最適化」かもしれませんが、以前は痛みを伴う非対話型プロセスだったものを実際にはかなり「メガ最適化」でしたユーザーの働き方を完全に変えたリアルタイムのインタラクティブなものに。

測定、ユーザーエンド要件、コンテキスト

ここでロバートのコメントが本当に好きで、たぶん私が望んだことを言えなかった:

じゃあね この種の変化が「それだけの価値」ではないと主張する人はいません。あなたは具体的な利益を実証することができました。多くのいわゆるマイクロ最適化はできません。

これは、多くの場合リアルタイム要件を伴う非常にパフォーマンスが重視される分野で作業しているにもかかわらず、邪魔にならないように微調整を検討する唯一の時間です。

そして、私は測定だけでなく、そのユーザー側を強調したいと思います。私は現在の分野(かつてはgamedev)に最初にユーザー/ファン、次に開発者として来たという点で奇妙です。したがって、技術的なパズルを解くようなプログラマーを興奮させる通常のことには決して興奮しませんでした。私は彼らに負担を感じましたが、私が他のユーザーと共有したユーザー側の夢を通して彼らに耐えました。しかし、それは私が何かを最適化しているかどうかを確認するのに役立ちました。それはユーザーに本当の利益をもたらします。これは、目的のないマイクロ最適化に対する私の予防策です。

私は自分の意見ではプロファイラーと同じくらい重要です。なぜなら、キューブを10億のファセットに細分割して、キャラクターや乗り物などの実世界の生産モデルを絞るようなことをした同僚がいたからです。彼らの結果は、「技術デモ」の意味では印象的でしたが、実際のユーザーにはほとんど役に立たなかったのです。なぜなら、彼らは実世界のユースケースに合わないケースのプロファイリングと測定、ベンチマークを行っていたからです したがって、最初にユーザーにとって重要なことを理解することは非常に重要です。ソフトウェアのようなものを考えて使用することを学ぶか、ユーザーと協力する(理想的には両方ですが、少なくともユーザーと協力する)ことです。


2
じゃあね この種の変化が「価値がある」とは誰も主張しません。あなたは具体的な利益を実証することができました。多くのいわゆるマイクロ最適化はできません。
ロバートハーベイ

1
@RobertHarveyそれは私が作ることを望んでいたポイントのようなものだった、一部の人はなど、測定、実際には必ずしも顕微鏡ではありませんが、それは文脈に依存しすぎだ「マイクロ最適化」と呼んで以来のisset対がstrlen焦点で、より非常に小さいと思われますコンテキストと測定値がありません。:-D
ドラゴンエナジー

1
@RobertHarvey「マイクロ最適化」に否定的なコンテキストがある場合、間接的ではありますが、これらの測定値、コンテキスト、およびユーザーエンドのニーズがない傾向があると言いたいと思っていました。誰も使用していないことを除いて、クールなものから地獄を最適化した同僚がいたので、最後のケースについても続けることができました。適切な最適化にはユーザー側の理解が必要だとさえ思います。そうでなければ、ユーザーが気にしないものをプロファイリングして調整することができます。
ドラゴンエネルギー

1
いくつかの最適化は差し迫ったニーズによって推進され、他の最適化は好奇心(知的追求と冒険心)によって推進されます。両方が必要です。ドラゴンエナジーのストーリーでは、おそらく「差し迫ったニーズ」ではなかったでしょう。アーティストは、各編集後24秒までレンダリング結果が表示されないことについて大声で文句を言わなかったからです。実際、プログラマーが速度記録を打破するためのあらゆる努力に投資するまで、ユーザーはそれがどれほど速いかを知らないかもしれません。需要に駆動を制限することはビジネス上理にかなっていますが、そうすると驚くべき最適化の機会やゲームチェンジャーを見逃します。
rwong

1
ビジネス感覚といえば、収益化の問題もあります。すべての動き(たとえば、パフォーマンスの最適化に取り組んでいるプログラマー)には費用がかかり、ビジネスに意味を持たせるために費用を回収する必要があります。したがって、プログラマーがビジネスマネージャーから承認を得る必要がある場合、ゲームを変える速度の改善を「販売」できるか、または「節約」できるかどうかを尋ねる必要があります。
rwong

0

私はこのように言います-マイクロ最適化は、ボトルネックではない何かを最適化するプロセスです。たとえば、プログラムが2つの関数AとBを呼び出し、Aが完了するのに100ミリ秒かかり、Bが2マイクロ秒かかる場合、関数Bの最適化を続けます。これは重要ではないだけでなく、絶対に間違っています。ただし、関数Bの最適化は最適化と呼ばれ、マイクロ最適化ではありません。最適化の重要性は異なります。他に何もする必要がなく、プログラムにバグがないとしましょう。そうです、それは重要です。しかし、一般的に優先順位があります。関数Cを追加/作成する必要があるとしましょう。関数Cを作成すると、その機能を使用せずにプログラムを高速化するよりも多くのお金が得られると思う場合は、最適化に進みます。それ以外の場合は、機能を追求します。また、パフォーマンスに重点を置いた経験豊富なプログラマーは、最適化に多くの時間を費やすことなく、高速プログラムを作成するだけです。少なくとも彼らは、どのツールを使用し、何年も無意味な(ミクロを読む)最適化を行ってはならないかを知っています。


この投稿は読みにくい(テキストの壁)。それをより良い形に編集してもいいですか?
グナット
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.