6/18 に Gemini CLI と Code Assist 拡張の提供が終わり、私自身も gemini を叩いていたスケジュール一式を Antigravity CLI へ寄せました。乗り換えた直後にまず感じたのは「ターミナルに戻ってくるのが速い」という曖昧な印象です。Go 製の単一バイナリになったのだから速いはず、という前提も頭にはありました。ただ、印象は印象でしかありません。個人開発で4つのサイト(Dolice Labs)の更新を自動化していると、CLI は1日に数十回起動されます。ここで起動が 0.4 秒変わるなら、運用全体では無視できない差になります。曖昧な体感を、誰でも再現できる数値に変えておきたいと考えました。
なぜ time antigravity --version では測ったことにならないのか
最初に多くの人がやるのは、こうした素朴な計測です。
time antigravity --version
# antigravity 2.0.3
# antigravity --version 0.18s user 0.04s system 88% cpu 0.249 total
この 0.249 秒には、いくつもの別物が混ざっています。シェルが PATH を解決してプロセスを起動する時間、ディスクからバイナリを読み込む時間(初回は特に遅い)、そしてバージョン文字列を出すだけの最小処理。さらに致命的なのは、1サンプルしか取っていないことです。2回目に同じコマンドを叩くと、OS のファイルキャッシュが温まっていて 0.08 秒で返ってくる、ということが普通に起こります。どちらが「本当の起動時間」なのでしょうか。
答えは「目的によって両方とも必要」です。スケジュール実行のように同じバイナリを連続して叩くなら、温まった状態(ウォーム)の中央値が現実に近いです。一方、滅多に起動しないツールや、デプロイ直後の最初の1回を気にするなら、キャッシュが冷えた状態(コールド)が効いてきます。素朴な time はこの区別を持たず、サンプル数も1なので、計測としては成立していないのです。
hyperfine でウォームの分布を取る
そこで hyperfine を使います。Rust 製のベンチマークツールで、ウォームアップ実行・複数回サンプリング・統計処理・外れ値の警告までやってくれます。
# macOS
brew install hyperfine
# Debian/Ubuntu
sudo apt install hyperfine
まずウォーム状態の起動レイテンシです。
hyperfine --warmup 5 --runs 50 \
'antigravity --version' \
'gemini --version'
--warmup 5 で計測前に5回空打ちしてキャッシュを温め、--runs 50 で50サンプル取ります。私の手元(M2 / macOS 15)での結果は次のようなものでした(環境依存の参考値です。絶対値ではなく差を見てください)。
Benchmark 1: antigravity --version
Time (mean ± σ): 28.4 ms ± 2.1 ms
Range (min … max): 25.9 ms … 34.7 ms 50 runs
Benchmark 2: gemini --version
Time (mean ± σ): 186.3 ms ± 9.4 ms
Range (min … max): 171.2 ms … 208.5 ms 50 runs
Summary
'antigravity --version' ran 6.56 ± 0.61 times faster than 'gemini --version'
ここで初めて「速くなった気がする」が約 6.5 倍という数字になりました。これは妥当な差だと感じます。Node 製の CLI は起動のたびに Node ランタイムを立ち上げ、依存モジュールを読み込みます。Go 製の単一バイナリはそのオーバーヘッドがほぼありません。--version という最小処理で測っているので、ここで見ているのは純粋なプロセス起動コストです。
コールドスタートは「冷やしてから」測る
ウォームは連続実行の現実を表しますが、デプロイ直後やマシン再起動後の最初の1回は別物です。macOS でファイルキャッシュを正確に冷やすのは難しい(purge でも完全ではありません)ので、私は「比較条件を揃える」方向で対処しています。両方のコマンドに同じ --prepare を与え、計測の直前に毎回同じ「冷却もどき」を挟むやり方です。
hyperfine --runs 20 \
--prepare 'sync; sleep 0.3' \
'antigravity --version' \
'gemini --version'
--prepare は各計測の前に実行され、その時間は計測に含まれません。これで「直前に必ず一拍置く」条件を両者に等しく課せます。真のコールドスタートではありませんが、少なくとも「片方だけ温まっている」という不公平は消えます。注意点として、初回起動時に macOS の Gatekeeper がバイナリを検証して数百ミリ秒持っていくことがあります。これはツールの実力ではなく OS の都合なので、xattr -d com.apple.quarantine $(which antigravity) で検疫属性を外してから測ると、ブレが落ち着きます。
起動コストと「実際にエージェントを動かすコスト」を混同しない
ここが最大の落とし穴です。antigravity --version は速くても、antigravity run "リファクタして" のような実行はモデル呼び出しのネットワーク往復が支配的で、CLI の起動が速いことの恩恵はほとんど見えません。起動レイテンシの改善が効くのは、あくまで「CLI を何度も起動するが、各回の仕事は軽い」ワークロードです。
両者を切り分けるために、私は計測対象を次の3層に分けています。
第1層:純粋な起動コスト
ネットワークを伴わない --version だけを測ります。ここが Go バイナリ化の恩恵が最も素直に出る層です。
第2層:ローカル完結の軽い処理
設定の読み込みやスラッシュコマンド一覧の表示など、ディスクと CPU だけで完結する処理です。
第3層:モデル往復あり(参考扱い)
実際のエージェント実行はネットワーク往復が支配的で、分散が大きく、起動の差はノイズに埋もれます。
# 1) 純粋な起動コスト(ネットワークなし)
hyperfine --warmup 5 'antigravity --version'
# 2) ローカル完結の軽い処理(設定の読み込み・スラッシュコマンド一覧など)
hyperfine --warmup 3 'antigravity --help'
# 3) モデル往復あり(参考。分散が大きく、起動の差はノイズに埋もれる)
hyperfine --runs 5 'antigravity run --quiet "say ok"'
3層目は分散が非常に大きく、これを「CLI が速い/遅い」の根拠にしてはいけません。起動の話をしているのに、測っているのはモデルの混雑具合だった、という取り違えは本当によく起きます。起動を語るなら 1) と 2) だけを根拠にすべきだと考えています。
自動運用での積み上がりを見積もる
個人開発の自動化では、起動の差が1回ぶんでは小さくても、回数で効いてきます。私のスケジュール群は4サイト合わせて1日あたりおおよそ 60 回、ビルド前後の検証やログ収集まで含めると CLI を起動します。ウォーム中央値の差を仮に 0.16 秒とすると、
0.16 秒 × 60 回/日 = 9.6 秒/日
9.6 秒 × 30 日 ≒ 4.8 分/月
数字にすると月5分弱です。これを「誤差」と見るか「積もる無駄」と見るかは運用規模によります。CI のステップで CLI を多数回呼ぶパイプラインや、フックで毎コミット起動する構成では、この係数(起動回数)が一桁増えるので、起動レイテンシは無視できないコストになります。逆に、1日数回しか叩かないなら起動の差は実務上ほぼ意味がないので、この場合は起動の最適化に手を入れず、より効く別の箇所に時間を割くことを推奨します。体感ではなく回数 × 差で考えるのが、ここでの実用的な判断基準です。
結果を JSON で残し、回帰を CI で止める
一度測って満足するのではなく、バージョンアップで遅くならないかを継続的に見たいところです。hyperfine は --export-json で機械可読な結果を出せます。
hyperfine --warmup 5 --runs 50 \
--export-json bench.json \
'antigravity --version'
これを使って、p95 がしきい値を超えたら CI を落とす小さなゲートを書けます。平均ではなく上振れを見るのがコツです。ユーザー体験を壊すのは平均ではなく、たまに刺さる遅い回だからです。
#!/usr/bin/env bash
# bench-gate.sh — 起動レイテンシが基準を超えたら exit 1
set -euo pipefail
THRESHOLD_MS = 80 # この値を超えたら回帰とみなす
hyperfine --warmup 5 --runs 50 \
--export-json bench.json \
'antigravity --version' > /dev/null
# times 配列から p95 を計算(平均ではなく上振れを見る)
P95_MS = $( python3 - << 'PY'
import json
times = sorted(json.load(open("bench.json"))["results"][0]["times"])
p95 = times[int(len(times) * 0.95) - 1] * 1000
print(round(p95, 1))
PY
)
echo "p95 startup: ${ P95_MS } ms (threshold ${ THRESHOLD_MS } ms)"
if awk "BEGIN { exit !(${ P95_MS } > ${ THRESHOLD_MS }) }" ; then
echo "🛑 起動レイテンシが回帰しました"
exit 1
fi
echo "✅ 起動レイテンシは基準内です"
このゲートを CLI を更新するワークフローに挟んでおけば、「いつの間にか起動が重くなっていた」を自動で検知できます。しきい値は自分の環境のウォーム中央値に少し余裕を持たせた値(私は中央値の約 2.5 倍)から始め、運用しながら締めていくのが現実的です。
まず手元で hyperfine --warmup 5 'antigravity --version' を一度走らせ、自分の数字を持つところから始めてみてください。体感を数字に変えると、どこを速くすべきか、そもそも速くする価値があるのかが、驚くほど冷静に見えてきます。