Claude Code と一緒に Go アプリの CPU 負荷を削減した話


こんにちは、エンジニアの山口です。

今回は、私が最近経験した「高い CPU 負荷」という問題を、Claude Code と一緒に解決した話をしたいと思います。結論から言うと、数時間で 26.07%の CPU 使用率を 1.67%まで削減できました。

「CPU 負荷が高いんだけど…」から始まった

ある日、Go で実装した GraphQL API サーバーの CPU 使用率が想定よりかなり高いことに気づきました。

私:「CPU の負荷が思ったより高いです。ローカルで確認しようかと思います。pprof で確認できますか?」

この何気ない質問から、Claude Code との効率的なペアプロが始まりました。

Claude Code とのやり取りで見えてきたボトルネック

pprof セットアップと分析手順を丁寧に教えてもらった

正直、pprof なんて普段使わないので、どうやって使うのか全く分からなかったのですが、Claude Code が丁寧に手順を教えてくれました。

まず、コードに pprof のエンドポイントを追加:

import _ "net/http/pprof"

r.PathPrefix("/debug/pprof/").Handler(http.DefaultServeMux)

そして、以下の詳細な手順を教えてもらいました:

# 1. サーバー起動
air -c .air.api.toml

# 2. 別ターミナルでプロファイル収集開始
# 60秒間CPUプロファイルを収集(画面操作中のデータを取る)
curl http://localhost:8082/debug/pprof/profile?seconds=60 > cpu_profile.pprof

# 3. 画面をぽちぽち操作
# 60秒間、負荷が高そうな操作を実施

# 4. 結果を確認
# オプション1: グラフィカルに見る(おすすめ)
go tool pprof -http=:8080 cpu_profile.pprof

# オプション2: テキストで見る
go tool pprof -top cpu_profile.pprof | head -30

# オプション3: 詳細ログを出力
go tool pprof -top -cum cpu_profile.pprof | head -50 > cpu_analysis.txt
echo "top50" | go tool pprof cpu_profile.pprof > cpu_detailed.txt

プロファイル結果を Claude Code に丸投げしたら即座に原因特定

ブラウザで炎グラフ(Flame Graph)を見てみたんですが、初めて見るグラフで正直よく分かりませんでした。

そこで、cpu_profile.pprofcpu_detailed.txt を Claude Code に丸投げしてみたところ、すぐに原因を特定してくれました。

「こういう大量のテキストログを瞬時に分析して問題箇所を特定できるのは、まさに AI ならではの強みだな」と感じました。人間だったら、このログを読み解くだけで相当時間がかかったと思います。

「これ、ボトルネックっぽくない?」

Claude Code が分析した結果を見て、私は思わず言いました。

私:「26.07%: service/car.CarSettings ってこれはボトルネックそうですね?」

Claude Code は即座にコードを分析し、問題の核心を突きました:

func (r *Repository) ListCarMaker(ctx context.Context) ([]*domain_car.CarMaker, error) {
    
    content, err := r.storageClient.Read(ctx, filepath.Join("local/json_data", config.GetConfig().APICarInfoJSONFileName))
    var carJson entity.CarJson
    if err := json.Unmarshal(content, &carJson); 
}

「でも、これってプロジェクトの慣例に反してない?」

Claude Code の提案は技術的には正しかったのですが、私にはコード見た時に違和感がありました。

私:「これは最小の変更になってる?プロジェクト全体の慣例に反してないか?」

Claude Code は柔軟に対応してくれました。プロジェクト全体の実装方針を維持しつつ、プロジェクトの命名規則に従った実装を提案:

type Repository struct {
    storageClient storage.StorageClientInterface
    redis         *redis.Client

    
    cachedCarJson *entity.CarJson
    cacheMutex    sync.RWMutex
    cacheExpiry   time.Time
}

func (r *Repository) getCarJsonData(ctx context.Context) (*entity.CarJson, error) {
    
    r.cacheMutex.RLock()
    if r.cachedCarJson != nil && time.Now().Before(r.cacheExpiry) {
        defer r.cacheMutex.RUnlock()
        return r.cachedCarJson, nil
    }
    
}

結果:CPU 使用率が劇的に改善

最初の CarSettings 最適化だけで、CPU 使用率は 26.07%から 1.67%まで削減されました。実に 94%の削減です。

さらに欲が出た私:「他に、リクエスト毎に Unmarshal してパフォーマンスに影響がありそうなところはある?」

Claude Code は他のファイルも同様の問題を抱えていることを特定し、すべて最適化してくれました。

CI/CD で詰まったときも即座にサポート

変更をプッシュしたら、CI/CD でモック生成エラーが発生。でも、Claude Code がすぐに解決策を提示してくれました。

go generate ./...

「こんなコマンド一つで解決するんだ」と、改めて Claude Code の知識の幅広さに感心しました。

Claude Code とうまく協働するコツ

今回の経験から学んだことをまとめます:

1. 具体的に聞く

「パフォーマンスを改善して」より「pprof で確認できますか?」の方が効果的でした。

2. プロジェクトの文脈を伝える

「これはプロジェクトの慣例に反してないか?」と確認することで、チームに馴染む実装になりました。

3. 段階的に進める

一気に全部やろうとせず、まず一番大きな問題を解決し、その後で追加の改善を行いました。

Claude Code は「答えを出すツール」じゃなくて「一緒に考えるパートナー」

今回一番感じたのは、Claude Code を「答えを出してくれるツール」というより、「一緒に問題を解決するパートナー」と思いました。

技術的な実装は Claude Code ができますが、ときにはプロジェクトの慣例に反する実装をすることがあります。
また、私はビジネス要件やアーキテクチャの判断に集中する。この役割分担がうまくいったときにスムーズに進むと感じています。

おわりに

今回の経験を通じて、AI エージェントを活用したパフォーマンス改善の効率性を実感しました。


Source link

関連記事

コメント

この記事へのコメントはありません。