2023 年 7 月,Ramp 的 Python 單體式(monolith)測試套件執行一次需要 45 分鐘,緩慢的測試拖累了全公司的合併佇列(merge queue)——工程師得空出半天時間,只為了盯著待處理的變更。兩年前,一篇內部文章就已指出緩慢的測試會損害工程生產力,但此後一直沒有採取任何行動。

團隊沒有投入大規模重寫,而是先進行測量:45 分鐘裡約有 38 分鐘來自 pytest 呼叫本身。效能剖析(profiling)顯示測試執行受 CPU 限制,因此第一項修正——更快的 CPU——單獨就讓執行時間縮短了約 50%,這是整個專案中最大的單一收益,也是找出成本最低的一項。

從那裡開始,工程師分頭進行低成本、並行的實驗,範圍限定在各自已有背景知識的領域:在自架執行器(self-hosted runner)上使用 Docker 層快取節省了一分多鐘;重寫 pytest-xdist 的工作拆分演算法節省了 2 至 3 分鐘;增加測試資料庫並調整 Postgres 連線設定,解決了超過 20 個 worker 同時存取同一資料庫時的鎖定爭用(lock contention)。並非每項實驗都有回報——將測試資料掛載到 RAM 中沒有帶來任何收益,因此被放棄——但每項實驗的成本都低到值得一試。

追求成本低、潛在上行空間大的實驗,並在收益遞減的那一刻停手

先進行測量(45 分鐘裡有 38 分鐘是 pytest 呼叫本身,且受 CPU 限制),意味著團隊修正了真正的瓶頸,而不是憑猜測行事。

先做槓桿最高、成本最低的修正(更快的 CPU,約 50% 的收益),建立了動能,並騰出時間探索風險更高的想法。

拆分成並行、低成本的實驗,讓團隊能快速驗證許多假設,而不是把所有籌碼押在一個大變更上。

將每項變更節省的時間繪製成圖,讓收益遞減曲線變得可見,為團隊提供了具體的停手訊號,而不是為了邊際收益繼續打磨。

先測量再調校,先修正槓桿最高的項目,然後並行執行一組低成本的實驗——並以每項收益逐漸縮小作為停手的訊號。

一週後,套件執行時間不到 5 分鐘,相較於原本的 45 分鐘,減少約 70% 以上。到了週末,新的改善每次只能從執行時間中削減幾秒(不到 5%),團隊以此作為停手的訊號,並將剩餘的想法移入長尾待辦清單,而不是繼續調校。

追溯依據

參考來源

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