データ分析パイプラインの処理時間が18時間かかっていました。1日は24時間しかないので、パイプラインが終わる頃には次のパイプラインを開始すべき時刻に近い状態でした。
根本原因は「同じデータを3回分析していた」重複計算でした。統合分析アーキテクチャに刷新した結果、18時間→3〜4時間(80%削減)に短縮しました。Claude Codeとこの大規模リファクタリングをどう進めたかを記録します。
Before:なぜ18時間かかっていたか
3つの処理パターンが独立して分析を実行
1短期処理の分析(1分/5分/15分/30分/1時間/4時間/日次/週次間隔): 約6時間2中期処理の分析(5分/15分/30分/1時間/4時間/日次間隔): 約5時間3長期処理の分析(4時間/日次/週次間隔): 約7時間4合計: 約18時間4時間間隔のデータは3つの処理パターンで全く同じなのに、3回別々に計算していました。411種類の分析指標 × 3回 = 実質1,233回の計算です。本当に必要なのは411回です。
なぜこうなっていたか
プロジェクト初期に処理パターンごとに独立したプログラムを作りました。「独立していれば影響範囲が限定的で安全」という判断でしたが、スケールした結果「同じ計算を何度もやる」非効率が深刻化しました。
刷新の設計
統合分析アーキテクチャ
1Before:2 short_term.py → 全時間間隔を独自に分析 → 分析指標計算 → 条件判定 → トリガー3 mid_term.py → 全時間間隔を独自に分析 → 分析指標計算 → 条件判定 → トリガー4 long_term.py → 全時間間隔を独自に分析 → 分析指標計算 → 条件判定 → トリガー5
6After:7 unified_analyzer.py → 全時間間隔を1回だけ分析 → 全分析指標を計算8 ↓(結果を共有)9 shortTermTriggerFileGenerator.py → 条件判定のみ10 midTermTriggerFileGenerator.py → 条件判定のみ11 longTermTriggerFileGenerator.py → 条件判定のみコア原則: 「分析指標の計算」と「条件の判定」を分離する。
unified_analyzer.py: 全分析指標を計算するが、条件判定は行わない*TriggerFileGenerator.py: 条件を判定するが、分析指標計算は行わない
AIとの大規模リファクタリングの進め方
ステップ1:現状分析をAIに依頼
1プロンプト:2short_term.py、mid_term.py、long_term.py の3ファイルを読んで、3重複している処理を特定してください。4各ファイルで共通して実行されている関数・メソッドを一覧化してください。AIが3ファイルを読み比べ、「4時間間隔のRSI計算が3回呼ばれている」「MACD計算が全ファイルで同一」といった重複を特定しました。
ステップ2:設計をAIと協議
1プロンプト:2重複計算を排除するアーキテクチャを3案提示してください。3各案のメリット・デメリットを比較してください。4制約: 既存のトリガーファイル形式(JSON)は変更しない。AIが提示した3案:
- 共通関数の抽出 — 重複部分を共通モジュール化
- 統合分析 + トリガー分離 — 計算と判定を分離(採用)
- キャッシュ方式 — 計算結果をファイルにキャッシュして再利用
案2を採用した理由は、キャッシュ方式だとファイルI/Oのオーバーヘッドがあり、共通関数の抽出は根本的な構造変更にならないためです。
ステップ3:段階的に移行
一括移行は危険なので、処理パターンごとに段階的に移行しました。
1Phase 1: long_term.py の分析指標計算を unified_analyzer.py に移動2 → テスト実行 → 本番デプロイ → 1週間運用3
4Phase 2: mid_term.py の分析指標計算を移動5 → テスト実行 → 本番デプロイ → 1週間運用6
7Phase 3: short_term.py の分析指標計算を移動8 → テスト実行 → 本番デプロイ → 最終確認各フェーズでAIに「このPhaseの変更だけを実装してください。他のPhaseには触れないでください」と明示しました。
ステップ4:回帰テストで安全を確認
1各Phaseの移行前後で:21. 回帰テストを実行 → 結果が一致することを確認32. 本番のトリガーファイル出力を比較 → 差分がないことを確認43. 処理時間を計測 → 改善を確認結果
| 指標 | Before | After |
|---|---|---|
| 処理時間 | 18時間 | 3〜4時間(80%削減) |
| コード重複 | 約2,000行 | 0行 |
| 分析指標計算回数 | 1,233回(411×3) | 411回 |
| バグ修正箇所 | 3ファイル | 1ファイル |
| メモリ使用量 | 低(逐次処理) | 一時的に増加(バッチ処理) |
AIに大規模リファクタリングを任せるコツ
1. スコープを明確に区切る
1❌ 「このシステムをリファクタリングしてください」2✅ 「long_term.pyのRSI計算部分だけをunified_analyzer.pyに移動してください」2. 「触らないファイル」を明示する
1制約:2- 変更するファイル: unified_analyzer.py, long_term.py3- 変更しないファイル: mid_term.py, short_term.py, トリガーファイルのJSON形式3. 移行前後の等価性を検証する
AIに「移行前後で出力が同一であることを確認するテストを書いてください」と依頼します。出力の等価性が保証できれば、移行は安全です。
4. ADRに設計判断を残す
移行後にDECISIONS.mdに記録します。将来のAIが「個別分析方式に戻す」提案をしたとき、「ADR-001で却下済み」と即座に判断できます。
学んだこと
1. 「動いているものを触るな」は負債を増やす
18時間のパイプラインを放置していたら、やがて24時間を超えて破綻していたでしょう。パフォーマンス問題は「いつか対処する」ではなく、構造的に解決すべきです。
2. AIは「段階的移行」が得意
「3つのファイルを一括で統合して」と言うと失敗しますが、「1ファイルずつ移行して」と言うと高精度で実行します。大規模リファクタリングは必ず段階的に進めましょう。
3. 計算と判定の分離は普遍的な設計原則
今回の「分析指標計算」と「条件判定」の分離は、データ分析パイプラインに限らず多くのシステムに適用できます。「データの生成」と「データの利用」を分離する設計は、重複排除の基本です。
まとめ
大規模リファクタリングで重要なのは以下の3点です。
- 計算と判定の分離: 全分析指標を1回計算 → 結果を各処理パターンで再利用。80%の処理時間削減
- 段階的移行: 3つの処理パターンを1つずつ移行。各段階で回帰テストと本番デプロイを挟む
- ADRで設計判断を記録: 将来のAI/人間が同じ議論を繰り返さないために