2023年7月、RampのPythonモノリスのテストスイートは実行に45分かかっており、遅いテストが全社のマージキューを滞らせていた。エンジニアは保留中の変更を見守るためだけに半日を空けていた。2年前には、遅いテストがエンジニアの生産性を損なうことを指摘する社内投稿があったが、それ以降何も行われていなかった。

大規模な書き換えに着手する代わりに、チームはまず計測した。45分のうち約38分はpytestの呼び出し自体に由来していた。プロファイリングによりテスト実行はCPUバウンドであることが分かったため、最初の修正であるより高速なCPUだけで実行時間は約50%短縮された。これはプロジェクト全体で最大の単一の改善であり、見つけるのに最も手間がかからなかったものでもあった。

そこからエンジニアは分かれて、それぞれがすでに文脈を持っている範囲に絞った、安価で並行な実験を行った。セルフホストランナーでのDockerレイヤーキャッシュにより1分以上を節約し、書き換えたpytest-xdistの作業分割アルゴリズムにより2〜3分を節約し、テストデータベースを増やしPostgresの接続設定を調整することで、20以上のワーカーが同じデータベースにアクセスした際のロック競合を解消した。すべての実験が実を結んだわけではない。テストデータをRAMにマウントする方法は効果がなく、取り下げられた。しかし、いずれも試す価値があるほど安価だった。

大きな潜在的上振れを伴う安価な実験を追い、効果が逓減した瞬間に止める

まず計測したこと(45分のうち38分はpytest呼び出し自体で、CPUバウンドだった)により、チームは推測ではなく実際のボトルネックを修正できた。

最もてこの効く、最も手間の少ない修正を最初に行ったこと(より高速なCPUで約50%の改善)が勢いを生み、よりリスクの高いアイデアを探る時間を生み出した。

並行で低コストの実験に分かれたことで、チームは1つの大きな変更にすべてを賭けるのではなく、多くの仮説を素早く検証できた。

変更ごとに節約された時間をグラフ化したことで逓減の曲線が可視化され、わずかな改善のために磨き続けるのではなく止めるための具体的なシグナルをチームに与えた。

調整する前に計測し、最もてこの効く項目を最初に修正し、その後は安価な実験のポートフォリオを並行して実行する。そして各改善の大きさが縮小していくことを止めるシグナルとして使う。

1週間後、スイートは5分未満で実行されるようになり、元の45分からおよそ70%以上の削減となった。週の終わりまでに新たな改善は実行時間を数秒(5%未満)しか削減しなくなっており、チームはこれを止めるシグナルとして使い、調整を続けるのではなく残りのアイデアを長期的なバックログに移した。

出典をたどる

出典

  1. Picking Low Hanging Fruit Ramp Engineering · builders.ramp.com ·