Dev Study
← 性能分析の土台
レッスン 6 / 10·約 9 分·第13期 性能分析

ボトルネックは、1つずつしか見つからない

リクエストがアプリケーションに届くまで
  1. ブラウザURL入力
  2. DNS名前→IP
  3. ルータ経路選択
  4. ロードバランサ振り分け
  5. Nginx受け口
  6. アプリ処理今ここ
  7. DB保存

前回までは数字の読み方と観測器の性質を見ました。今回は数字が読めた後の話です。直す場所を選んだ時点で、得られる速さの上限が決まっています。

まず結論

直列につながった経路では、全体の時間は各段の足し算です。だから効くのは最大の項だけで、小さい項をどれだけ削っても全体はほとんど動きません。

最大の項を削ると、次に大きい項が最大になります。「直したのに思ったほど速くならない」は、失敗ではなく足し算の構造です。

? 読む前に予測

2つの処理が順番に走る経路で、前半が全体の約8割、後半が約2割を占めています。前半を2倍速くしたら、全体は何倍になるでしょうか。

当てることが目的ではありません。外した予測ほど記憶に残るので、直感で選んでください。

抽象原理

順番に走るなら、全体は足し算

段1・段2・段3が順番に走り、前が終わらないと次が始まらないとします。全体の所要時間は各段の和です。それ以上でも以下でもありません。

和のうち 0.2 を占める項をゼロにしても、和は 0.2 しか減りません。どれだけ努力しても 0.2 以上は減らせないのです。一方 0.8 の項なら最大 0.8 減らせます。効くのは最大の項だけとはこの意味です。

もう一つ。最大の項を削ると残った項が相対的に大きくなり、次に測ると別の段が最大の項です。新しい問題ではなく、順位が入れ替わっただけです。

最大の項を削ると、最大の項が入れ替わる
段A全体の約8割
段B全体の約2割
最大の項(A)を削る
段A小さくなった
段Bこちらが最大に
最大の項(B)を削る
段Aまた最大に
段B小さくなった
  • 順位が入れ替わるだけで、和は毎回小さくなっている
  • 「また別のところが遅い」は進んでいる証拠
具体実物

80対20の2段で計ってみる

本教材の測定環境(Docker Desktop の Linux VM、aarch64、カーネル 6.10.14-linuxkit、CPU 2.0 相当に制限、Python 3.11.2)で、段Aと段Bが順に走る処理を作りました。仕事量の比は A : B = 4 : 1、各条件12回試行の最小値です。

直列2段。片方だけ速くしたときの全体の倍率コマンド出力
change A(units) B(units) total(ms) speedup
baseline 1200000 300000 17.87 1.00x
A made 2x faster (the bottleneck) 600000 300000 10.70 1.67x
A made 4x faster 300000 300000 7.06 2.53x
A made 10x faster 120000 300000 4.93 3.63x
A made INFINITELY fast (A removed) 1 300000 3.56 5.02x
--- now instead: B made 2x faster 1200000 150000 16.08 1.11x
B made 10x faster 1200000 30000 14.56 1.23x
B made INFINITELY fast (B removed) 1200000 1 14.07 1.27x

段Aを「2倍速く」しても、全体は 1.67 倍。 B が残るからです。

段Aを10倍にしても 3.63 倍、実質的に取り除いても 5.02 倍が上限。 右端の倍率は丸める前の値から出しているので、表示の ms 同士を割ると末尾がずれます。「INFINITELY fast」は units を1にしただけでゼロではなく、3.56 ms には呼び出しと計時の費用が残ります。上限が5倍なのは残る B が約2割だから。1 ÷ 0.2 = 5 と一致します。

段Bは取り除いても 1.27 倍。 どれだけ頑張ってもここより上に行けません。上限は努力の量ではなく、選んだ場所で決まります。

✓ ここまでの確認

全体の約8割を占める段を、実質的に取り除けたとします。全体は何倍まで速くなりますか。

抽象原理

法則の検証ではなく、足し算の帰結

上の結果を**「アムダールの法則を実証した」とは書きません。** 理由は2つです。

1つは、この関係の原論文(1967年の会議録)を本教材では入手できなかったためです。学術データベースは403を返し、大学のミラーとされる2つの URL は .pdf に HTTP 200 を返しながら、中身は認証のログイン画面の HTML でした。200 は本文の存在を意味しません。 読めていないものを「〜が述べている」とは書けません。

もう1つは、これが検証を要する法則ではなく足し算の性質だからです。段が順に走るなら合計は和で、残る項は消えません。名前を知らなくても導けます。身につけてほしいのは名前ではなく、部分の倍率と全体の倍率が一致しない理由です。

具体実物

最大の項が入れ替わるのを3手で見る

同じ処理で「最大の項を測り、それを6分の1にする」を繰り返しました。

最大の項を削るたびに順位が入れ替わる(同じ測定環境)コマンド出力
# Start from baseline. Fix A (the biggest). Then measure which stage is biggest.
step 0: A= 14.33 ms B= 3.52 ms total= 17.89 ms -> largest term is A
step 1: A= 2.34 ms B= 3.56 ms total= 5.89 ms -> largest term is B
step 2: A= 2.33 ms B= 0.53 ms total= 2.92 ms -> largest term is A

step 0 では A が最大です。A を6分の1にすると(step 1)、B は何も触っていないのに B が最大になります。B も6分の1にすると(step 2)、また A に戻ります。

step 1 で B が最大になったのは、前回の判定が誤りだったからではありません。 A を直したから B が最大になったのです。判定は正しく、対象が変わりました。

一方で合計は毎回減っています。17.89 → 5.89 → 2.92 ms。「また別のところが遅い」と「改善が効いていない」は別の状態で、ここでは前者だけが起きています。

✓ ここまでの確認

最大の段を直したところ、次の測定では別の段が最大になっていました。これはどう解釈すべきですか。

⇄ 2つを見比べる
具体例 A

直列経路の小さい段を直したとき

全体の2割の段を改善しても、残る8割が消えないので上限があります。本教材の測定環境では取り除いても 1.27 倍でした。効かなかったのではなく、効いてもそこまでの場所だったということです。

選んだ場所と倍率の上限表
直した段 全体に占める割合 実質的に取り除いた場合
段A 約8割 5.02倍
段B 約2割 1.27倍
具体例 B

DB編『掃除は4つの仕事をしている — そしてディスクは空かない』

行を削除して掃除を走らせても、ディスク使用率は下がりません。公式が "extra space is not returned to the operating system (in most cases)" と書いており、成功時にも起きます。見る指標は、下がったかではなく増え続けていないかです。

見る指標と判定できること表
見る指標 下がらないとき 判定
ディスク使用率 設計どおり 失敗の証拠にならない
使用量の増え方 平らなら正常 回収が効いているか

直列経路の改善と、データベースの掃除。層は違いますが、「効かなかった」の読み方に共通する構造は何でしょうか。

どちらも、期待した変化が出ないと「作業が間違っていた」と結論しがちです。その結論が成り立たない理由を考えてみてください。

この章のまとめ

  • 段が順に走る経路では、全体の時間は各段の和。効くのは最大の項だけ。
  • 倍率の上限は、選んだ場所が占める割合で先に決まる。 1 ÷ 残りの割合 で着手前に計算する。
  • 本教材の測定環境(Docker Desktop の Linux VM、12回試行の最小値)で、約8割の段は取り除いて 5.02 倍が上限、約2割の段は取り除いても 1.27 倍。読んでよいのは倍率と順序だけ。
  • 最大の項を削ると、残った項が最大になる。 同じ環境で A → B → A と3手で入れ替わった。前回の判定が誤りだったのではなく、直したことの帰結。
  • これは足し算の帰結であって法則の検証ではない。原論文を入手できていないため通称に帰属させない。
  • 「直したのに速くならない」と「直し方が間違っていた」は別の状態。上限を先に計算すれば取り違えずに済む。

自分の現場で確かめる

読んだだけでは身につきません。手元の環境で実際に見てみてください。

環境:

理解度チェック

読んだ直後は「分かった」と感じやすいものです。実際に解いて確かめてください。

問題 1 / 3正解: 0

直列経路で「最大の項だけが効く」と言えるのは、なぜですか。

用語集(4語)
直列経路
複数の段が順番に走り、前が終わらないと次が始まらないつながり方。全体の所要時間は各段の和。
最大の項
直列経路の和のうち最も大きい段。本教材の「ボトルネック」はこの意味。
倍率の上限
その段を取り除いても届かない、全体の倍率の限界。1 ÷ (残りの割合) で求まる。
アムダールの法則と呼ばれている関係
直列部分の割合が改善の上限を決めるという関係の通称。本教材は原論文を入手できていないため、この名前に帰属させない。