プログラム最適化の90/10ルールの意味は何ですか?


67

ウィキペディアによると、プログラム最適化の90/10ルールは、「プログラムの実行時間の90%がコードの10%の実行に費やされる」と述べています(ここの2番目の段落を参照)。

私はこれを本当に理解していません。これはどういう意味ですか?実行時間の90%をコードの10%だけを実行するために使用するにはどうすればよいですか?では、コードの他の90%はどうでしょうか?わずか10%の時間でどのように実行できますか?


50
コードの一部は、他の部分よりも頻繁に実行される場合があります。結局のところ、それがループの目的です。実際には、ほとんど常にいくつかの部分が実行されている方法より頻繁に他より。
キリアンフォス16年

147
ソフトウェアプロジェクト期間の90/10ルールを聞くまで待ちます。「プロジェクトの90%が、割り当てられた時間の最初の90%を占有します。プロジェクトの最後の10%が、割り当てられた時間の残りの90%を占めます。」
ポールD.ウェイト

3
ここでの混乱:「実行に時間がかかる」。検討してくださいa++; for(i=0;i<100;i++){b++;} for(i=0;i<100;i++){print(xyz);}。最初のforループは最初の文よりも多くの時間を費やしますが、2番目のforループは最初のforループよりも約1000倍多く時間を費やしますが、実行しません。それはそれを費やして印刷を待っています。そのため、実行に費やされる時間と、コードが担当する時間には差があります。
マイクダンラベイ16年

32
@ Paul_D._Waiteプロジェクトの90%が90%の時間を費やし、残りの90%がさらに90%の時間を要し、非収束シリーズを下ってプロジェクトがないという結論に至ると思いました無限の時間で完了または完全にデバッグされたことはありません。
nigel222

9
実際の例として、私が取り組んだいくつかのコード(科学モデル)は、大量のコード(〜10K行)を使用してモデルを読み込んでセットアップし、数百行をループして実際の計算を行いました。しかし、その短いループはn ^ 4(3つの空間次元が何千ものタイムステップで繰り返される)であったため、計算に数日かかりました。そのため、実際の比率はおそらく99%/ 1%のよう
jamesqf

回答:


184

ここでは、2つの基本的な原則があります。

  • 一部のコードは、他のコードよりも頻繁に実行されます。 たとえば、一部のエラー処理コードは使用されない場合があります。一部のコードは、プログラムを起動したときにのみ実行されます。プログラムの実行中に他のコードが繰り返し実行されます。
  • いくつかのコードがかかるくらいの他のコードよりも実行に長いです。 たとえば、データベースでクエリを実行したり、インターネットからファイルを取得したりする1行は、おそらく数百万の数学演算よりも時間がかかります。

90/10ルールは文字通り真実ではありません。それはプログラムによって異なります(特定の数値90と10には何らかの根拠があるとは思いません。おそらく誰かがそれらを薄い空気から引き離したのでしょう)。しかし、ポイントは、プログラムをより速く実行する必要がある場合、おそらくそれを実現するのに重要なのは少数の行だけです。ソフトウェアの遅い部分を特定することは、多くの場合、最適化の最大の部分です。

これは重要な洞察であり、新しい開発者にとって直観に反すると思われる決定がしばしば正しいことを意味します。例えば:

  • 馬鹿げた、単純な方法で物事を行っているとしても、「より良い」ことはあなたの時間の価値がないコードがたくさんあります。アプリケーションXYZのより効率的な検索アルゴリズムを作成できますか?はい。ただし、実際にはすべての値の単純な比較には、数千の値がある場合でも、些細な時間がかかります。だから、それだけの価値はありません。新しい開発者が不必要な最適化を回避するのは難しい場合があります。なぜなら、学位プログラムでは、「正しい」(最も効率的な)アルゴリズムの作成に多くの時間が費やされたからです。しかし、現実の世界では、正しいアルゴリズムとは、十分に高速に動作し実行されるものです。
  • コードをより長く、より複雑にする変更は、パフォーマンスの向上につながる可能性があります。 たとえば、アプリケーションFOOでは、1回のデータベース呼び出しを避けるために、数百行の新しいロジックを追加する価値があります。

6
特に注目すべきは、ソート関数のようなものを使うと、エレガントなアルゴリズムを完全に機能させてバグのないものにするよりも、すべてのケースでダムのシンプルなアルゴリズムを正しい動作にするのが(開発時間で)はるかに高速で簡単です。(アカデミア以外でソートアルゴを記述する唯一の理由は、ライブラリを構築している場合、またはライブラリなしでプラットフォームで作業している場合です...)
StarWeaver

5
shouldioptimize.comへのリンクを追加する必要があると思います:)
Ivan Kolmychek

13
90/10は、よく知られている80/20パレート原則en.wikipedia.org/wiki/Pareto_principle
fernando.reyes

2
@StarWeaverだからこそ、C ++のように、非常に効率的なソートを、くだらないバブルソートと同じかそれよりも簡単に書く言語が重要です。このような「あらかじめパッケージ化された」アルゴリズムとコードは、使用時に複雑さを引き起こすことなく、非常に大幅に最適化できます。
-Yakk

6
@IvanKolmychekそのサイトは誤解を招くものです。確かに、この種のコスト分析は考慮すべき1つの要素ですが、ユーザーエクスペリエンスのような他の要素もあります。最適化しないことで多くのお金を節約できるかもしれませんが、人々があなたのサイトをいらいらさせると、多くの収入を見逃すかもしれません。
jpmc26

21

これは自然の法則ではなく、幅広い経験から生まれた経験則です。80/20ルールとも呼ばれ、大まかな概算にすぎません。

ループ、ブランチ、その他のフロー制御。

ifがある各場所には、1つのブランチがあり、他のブランチよりも頻繁に使用されます。したがって、実行時間の多くは、他の部分ではなく、プログラムのその部分の実行に費やされます。

ループが複数回実行される各場所には、周囲のコードよりも多く実行されるコードがあります。したがって、より多くの時間がそこで費やされます。

例として、以下を検討してください。

def DoSomeWork():
    for i in range(1000000):
        DoWork(i)
    except WorkExeption:
        print("Oh No!")

ここではprint("Oh No!")、最大で1回だけ実行されますが、多くの場合は実行されませんが、DoWork(i)約100万回実行されます。


7
これを80/20ルールと呼ぶと、プログラミングだけでなくより広く適用されるパレートの原則と混同する可能性があります。たぶん90と10は、この意味が重複しない便利な数字です。
-trichoplax

29
これは、パレートプリンシパルのインスタンスです。数値の両方のペアは等しく任意です
-Caleth

2
パレート原理の80/20分割には数学的な根拠があります。それらは、「たくさん」と「少し」を表す単なる想像上の数字ではありません。
モイル

1
@Moyli-はい、「80/20の分割には数学的根拠があります...」が、現実の世界では、正確に80/20になることはありません(偶然ではありませんが、めったにありません)。
ケビンフェガン

2
@trichoplaxパレート原理はここで非常によく適用されます。原因(コード行)の20%が結果(ランタイム)の80%を引き起こす
njzk2

16

ループ。

私はそこで止めたいと思っています!:-)

このプログラムを検討してください

1. do_something

2. loop 10 times
3.    do_another_thing

4.    loop 5 times
5.        do_more_stuff

1行目は1回実行され、3行目は10回実行されます。各行を順番に見る

1 1   0.8%
2 10  8.3%
3 10  8.3%
4 50 41.3%
5 50 41.3%

2行が実行時間の83%を占めます(すべての行の実行にほぼ同じ時間がかかると仮定します。したがって、プログラムの40%が> 80%かかります。

より大きな実世界の例ではこれが上昇するため、ランタイムの大部分を占めるのはごくわずかな行だけです。

90/10ルール(または80/20と呼ばれることもある)は、「経験則」であり、ほぼ正しいです。

パレート原理も参照してください


2
ほぼ真実だと言う代わりに、多くの場合、少なくとも 90%の時間をコードのごく一部(最大で 10%)の実行に費やしていると思います。明らかに、すべての部分がほぼ同じ時間を費やしてプログラムを実行することは可能ですが、それはまれです。
supercat

パレート原理を参照するための+1。詳細な説明は、この素晴らしいVsauceビデオで見ることができます。
ラドゥムゼア

5

実行時間のみについて尋ねたように、この例は役に立つかもしれません:

int main() {
    sleep(90); // approximately 10% of the program.
    // other 90% of the program:
    sleep(1);
    sleep(1);
    sleep(1);
    sleep(1);
    sleep(1);
    sleep(1);
    sleep(1);
    sleep(1);
    sleep(1);
    sleep(1);
    return 0;
}

もう少し真面目に言うと、実際のコードではほとんど常にループで(ではなくsleep(90);)重い関数を呼び出し、残りの10%はシングルパス計算を実行することを意味します。

別の例は、一部のHAサービスでのエラー処理です。高可用性サービスは、通常の条件下で無限の時間動作するように設計されています。通常は99%の時間で動作しますが、エラーが発生した場合は、エラー処理と回復を実行することがあります。これは、サービス自体よりも論理的に複雑な場合があります。


素敵な、私は誰かがこの極端な例を投稿することを望んでいた、それは明らかに違いを示しています。
-djechlin

3

90/10の推論は、コードのごく一部が他のコードよりも繰り返し使用されることを意味します。これは、コードのこの10%に開発/最適化の作業の90%を集中する必要があることを示唆するためによく使用されます。

Microsoft WordOpenOfficeなどの通常のテキストプロセッサを考えてください。

  • 設定ダイアログはあまり使用されません。
  • 文字を描くサブルーチンは常に使用されます。

このことわざは経営科学でも使用されています...これは人生そのものへの教訓です...


6
Microsoft Wordが単純な場合、複雑な例は何ですか?
ピーターモーテンセン

意味のない@PeterMortensen
グレートダック

@PeterMortensen Emacs、明らかに。
ムル

2

次のようなプログラムを想像してください。

print "H"
print "e"
print "l"
print "l"
print "o"
for i=0 to 1,000,000
    print "How long now?"
next
print "B"
print "y"
print "e"

11行中3行がforループであり、このかなり小さなコードにどれだけの時間を費やしているのか、11行あることに注目してください。他の8行は単に1文字を印刷しているだけです。したがって、一部のコードは短い場合もありますが、実行される頻度と時間がかかることはわかりません。


0

ループに加えて、他のすばらしい回答で言及されているように、考慮すべきDRYの原則もあります。よく書かれたオブジェクト指向コードには、再利用可能な部分がたくさんあります。定義上、再利用されるパーツは、一度だけ実行されるものの少なくとも2倍の頻度で使用されます。多数のオブジェクト指向コードがある場合、いくつかのクラスとメソッドを何度も再利用し、他のいくつかのコードを一度だけ再利用する可能性があります。

他の回答で述べたように、1回だけ使用されるコードを改善するよりも、頻繁に使用されるコードを改善する努力をする方がおそらく良いでしょう。


2
多くのコードを再利用できますが、それらのすべてがまれに実行される可能性があります(依然として重要です)。
ピーターモーテンセン

@PeterMortensen「重要だが頻繁ではない」は、「ほぼ毎秒再利用され、可能な限り高速にする必要がある」と同じではない
グレートダック

@TheGreatDuckと私はそれが彼の言っていることだとは思わない。まれにしか実行されないコードを持つこともできます、できるだけ早く実行したいからです。たとえば、エラー回復を考えてみましょう。アプリケーションによっては、システムが再び動作するまでに少し時間がかかる場合があります(5分、1時間、またはそれ以上)。ただし、たとえば、フライトシステムでエラーが発生した場合は、できるだけ早くエラーを発生させてください。そうでない場合、文字通りの意味で「ダウン」および「クラッシュ」します。
VLAZ

これは、DRYがオブジェクト指向を必要とすることを暗示しているようですが、もちろんそうではありません。無料の機能などによって再利用も同様に促進されます
underscore_d

@vlazそれは本当ですが、問題は飛行機の中で....すべてが高速で実行する必要があるということです。
グレートダック

0

それはルールではありません、それはウィキペディアを編集して、いくつかの数字を空っぽから引き出してルールと呼んだ単なる男です。他の文脈でよりしっかりと確立されているパレート原則と比較してください。この「ルール」の正確性について(もしあれば)どのような研究が行われたかを知りたい。

しかし、基本的にあなたの質問に対する答えは、他のコードよりもはるかに頻繁に実行されるコードがあるということです。多くの場合、ループがこの理由です。他の理由は、時間のかかる呼び出しです。たとえば、Webサービスやストレージメディアなどの外部リソースへの呼び出しです。


それは人々が経験則として使用する合法的なものです。
グレートダック

これが経験則として広く使用されていることを示唆しているなら、その証拠も見たいです!それとも、もう一つの意見が薄い空気から引き出されたが、事実として暗示されているのか?
ブラッドトーマス

あなたが実際にした場合読んで Wikipediaの記事をあなたはアスカーによって参照の引用は、この引用を持っていることを参照してくださいね:amazon.com/Every-Computer-Performance-Book-Computers/dp/...私は個人的に使用して、それを見たことがありません、しかし、あなたは私の意見で失礼と却下として出会ったので、私は答えました。明らかに10%は誰かが作った数字です。プログラムを非効率にすることで、好きな数にできます。ただし、ソフトウェアエンジニアリングで使用されている用語であるかどうかは、ここで何人がその存在に同意するかを考えると、明らかに議論の余地がありません。
グレートダック

さて、それが参照しているはずの研究を見るためだけに本を買うつもりはありません...証拠を示す引用を投稿できますか?または、実際に何も見ませんでしたか?
ブラッドトーマス

1
@BradThomas:Wikipediaを編集していた人が90-10ルールを発明したという理論に対する証拠は、Wikipediaが存在する何年も前に90と10の数字で広く引用されていたことです。実際の原則は、コードの正確に10%がランタイムの90%を占めるということではなく、ほとんどのプログラムでコードのごく一部(-10%以下)がランタイムの大きな部分を占めるということです。 -90%以上の場合、コードのごく一部のパフォーマンスが10%改善されただけでも、他のすべての部分で1000倍以上の全体的な実行時間が短縮されます。
-supercat

0

これは「パレート原理」の再解釈であり、「多くの場合、効果の約80%は原因の20%に由来する」と述べられており、80/20ルールとしても知られています。この規則は、主に経済学に適用されるため、プログラミングに再利用されることは理にかなっています。

これは、長期間にわたって観察されてきた単なるパターンです。

これは、このようなパターンに関する非常に優れたビデオです。また、パレートの原理についても説明しています。

https://www.youtube.com/watch?v=fCn8zs912OE&ab_channel=Vsauce

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