- ルール 1: プログラムがどこで時間を消費するかは予測できない。ボトルネックは予想外の場所で発生するため、実際にボトルネックであることが証明されるまで高速化を試みてはならない
- ルール 2: 計測が先。速度調整は計測後にのみ行い、コードの一部が全体を圧倒しているときにだけ最適化を検討する
- ルール 3: 複雑なアルゴリズムは小さな n では遅い。複雑なアルゴリズムは大きな定数を持つため、n が頻繁に大きくならない限り単純な方法を使うべき。n が大きくなる場合でも、まずルール 2 を適用しなければならない
- ルール 4: 複雑なアルゴリズムはバグが多く、実装が難しい。単純なアルゴリズムと単純なデータ構造を使うことが望ましい
- ルール 5: データが核心。正しいデータ構造を選び、うまく整理すれば、アルゴリズムはほとんど自明に見えてくる。プログラミングの中心はアルゴリズムではなくデータ構造である
関連する哲学と引用
- ルール 1 と 2 は、Tony Hoare の 「早すぎる最適化は諸悪の根源」 という格言と同じ意味
- Ken Thompson はルール 3 と 4 を 「疑わしいときは単純な方法(Brute Force)を使え」 と再解釈した
- ルール 3 と 4 は KISS(Keep It Simple, Stupid) 設計哲学の例
- ルール 5 は Fred Brooks が『The Mythical Man-Month』ですでに述べていた内容で、
しばしば 「賢いオブジェクトを使って単純なコードを書く」 と要約される
1件のコメント
Hacker Newsのコメント
Jonathan Blowの講演を思い出した
彼は生産性の観点からアプローチしていた。Braid開発初期にはほぼすべてを単純な配列で実装し、ボトルネックが発生したときだけ修正していた
「速度やメモリよりも重要なのは、1つのプログラムを実装するのにかかる人生の時間だ」という言葉が印象的だった
Rule 1を本気で受け入れるなら、Rule 3〜5は自然についてくる
ボトルネックは予測できないという前提を認めるなら、単純なコードを書いて測定することが唯一の合理的な戦略になる
実際によく失敗するのは早すぎる最適化ではなく、早すぎる抽象化だ。不要な柔軟性のために複雑な階層を作り、それがかえって保守コストを押し上げる
90年代に深夜2時、データセット検索機能を実装しなければならなかったことがある
疲れていたのでひとまず線形探索で実装して後で直そうと思ったが、実際には4時間のテストで6秒しか差が出なかった
結局修正はしたものの、意味のある差はなかった
Rule 5には全面的に共感する
難しい問題ほどデータ構造とAPIの反復的改善によって解決される。構造がうまく定まれば、制御フローは自然になる
LLMはこうした構造的思考が苦手だ。複雑な制御フローはうまく提案するが、組み合わせ可能なデータ構造の設計は得意ではない
私は電子工学(E.E.)出身で、Rule 3のおかげでキャリア初期には大きな問題はなかった
しかし後に大規模システムへ移るとnが大きくなり、計算量が本当に重要になった
Rob Pikeが話していた時代の「ビッグアイアン」は、今でいう組み込み環境に近かった
2つのアルゴリズムで実装難易度が同じくらいなら、大きな入力で速いほうを選ぶ
関連記事: Less Than Quadratic
人はしばしば単純すぎるO(n²)アプローチを選び、本番で爆発するのを経験する
Pikeのルールは、従来の格言より優れていると思う
「早すぎる最適化は諸悪の根源」といった文は文脈が失われると誤解されやすい
Pikeのバージョンは明確で、誤用されにくい
「Rule 5は『賢いオブジェクトを使わせて、コードは愚かにしておけ』と要約できる」という昔の言い方があったが、
オブジェクト指向の時代にはむしろ複雑さを隠す誤った信念へと変質してしまった
10年以上同じコードベースを運用してきて、Pikeのルールを完全に体得した
KISS/DRY原則を守り、流行の技術より実績のある技術を維持することが、長期的には安定につながった
実際、私たちのチームの開発原則文書はPikeのルールとほぼ同じ内容だ
1990年代初頭のC++時代、双方向連結リストの代わりに単純な配列の再割り当てに変えたところ、
バグが消えただけでなく、むしろ速くなった。
高価な操作をより少ない頻度で行うことがよい戦略だと学んだ
「測定せずにチューニングするな」というルールと、Jeff DeanのLatency Numbers Every Programmer Should Knowを比べると興味深い
Deanは事前知識によって性能を予測できると述べている
結局、この2つの立場は両立できる。設計段階では感覚的に速そうな構造を選び、実装後には測定ベースで微調整すべきだ
Rule 1と2が絶対なのは、新しい問題を扱うときだけだ
同じドメインで繰り返しシステムを作っていると、ボトルネック箇所を事前に予測できるようになる
経験豊富な開発者なら、設計前からおおよその性能感を持てる