unified_analyzer キャッシュ層追加完了レポート
実装日時
2025-01-XX
概要
src/nexuscore/analyzer/unified_analyzer.py に「差分解析用キャッシュ層」を追加し、 同じプロジェクトを何度も解析するときのパフォーマンスを大幅に改善しました。
実装ステップ
1. キャッシュ戦略の決定
実装内容:
- 単位: プロジェクトルート単位でキャッシュを持つ
- キー: ファイルパス × ファイル内容ハッシュ(SHA256)
- キャッシュ内容: ファイルごとの解析結果(AST情報、依存関係、メタデータ)
- 永続化:
project_root/.nexuscache/analyzer_cache.jsonに JSON 形式で保存
2. キャッシュの永続化層(軽量版)
新規クラス: AnalyzerCache
実装内容:
_compute_file_hash(): ファイル内容のハッシュを計算load_cache(): キャッシュファイルを読み込みsave_cache(): キャッシュファイルに保存get_cached_result(): キャッシュから結果を取得should_analyze_file(): ファイルを解析する必要があるか判定update_cache_entry(): キャッシュエントリを更新clear_cache(): キャッシュをクリア
キャッシュフォーマット:
{
"version": 1,
"generated_at": "2025-01-01T00:00:00Z",
"project_root": "/path/to/project",
"files": {
"src/foo.py": {
"hash": "abc123...",
"result": {...},
"cached_at": "2025-01-01T00:00:00Z"
}
}
}
バージョン管理: キャッシュフォーマットのバージョンが異なる場合は無視して再生成
3. 差分検出ロジックの実装
実装内容:
UnifiedAnalyzer.run()メソッドで差分検出を実装- 現在のファイル一覧と各ファイルのハッシュを算出
- キャッシュファイルを読み込み、前回のハッシュと比較
- 変更のないファイルについてはキャッシュ結果を再利用
- 変更のあるファイル・新規ファイルだけ Tree-sitter を通す
効果: 変更のないファイルは再解析をスキップし、解析時間を大幅に短縮
4. UnifiedAnalyzer クラスの実装
新規クラス: UnifiedAnalyzer
実装内容:
__init__(): プロジェクトルート、キャッシュ設定を受け取るsetup(): パーサーをセットアップ_get_target_files(): 解析対象のファイルリストを取得run(): プロジェクト全体を解析するメインメソッド- キャッシュの読み込み
- 差分検出
- 変更のあるファイルの解析
- キャッシュの保存
- 統計情報のログ出力
API 設計:
UnifiedAnalyzer(project_root, use_cache=True): キャッシュ利用を ON/OFF できるパラメータ- 環境変数
NEXUS_ANALYZER_ENABLE_CACHEでデフォルト値を制御可能
5. graph_builder との整合性
実装方針:
graph_builderそのものは大きく変えず、unified_analyzer側で「graph_builder に渡す inputs」を差分ベースで組み立てるAnalysisResultオブジェクトのリストをgraph_builderに渡す形式は維持- キャッシュから取得した結果も
AnalysisResultオブジェクトとして再構築
6. テストの拡張
変更ファイル: tests/analyzer/test_unified_analyzer_e2e.py
追加テスト:
test_unified_analyzer_with_cache_first_run: 1回目実行時、キャッシュが生成されることを確認test_unified_analyzer_with_cache_second_run: 2回目実行時、キャッシュを使っても解析結果が同じ構造で返ることを確認test_unified_analyzer_cache_incremental_update: 片方のファイルだけ変更した場合、変更されたファイルだけ再解析されることを確認test_unified_analyzer_cache_performance: キャッシュ使用時のパフォーマンス改善を確認
7. ログ & 観測性
実装内容:
- キャッシュヒット数、再解析したファイル数、キャッシュファイルのパスをログ出力
- 統計情報を
run()の戻り値に含める:stats: 総ファイル数、キャッシュされたファイル数、解析されたファイル数、失敗したファイル数cache_info: キャッシュ有効/無効、キャッシュファイルパス、キャッシュヒット数、キャッシュミス数
8. ドキュメントの更新
変更ファイル: docs/testing_strategy_phase3.md
追加内容:
unified_analyzerのキャッシュ機能に関する検証項目を追加
変更ファイル一覧
変更ファイル
src/nexuscore/analyzer/unified_analyzer.pyAnalyzerCacheクラスを追加(キャッシュ管理)UnifiedAnalyzerクラスを追加(プロジェクト全体の解析を統合)- 環境変数
NEXUS_ANALYZER_ENABLE_CACHEでキャッシュを制御可能に - キャッシュバージョン管理を追加
tests/analyzer/test_unified_analyzer_e2e.py- キャッシュ機能のテストを追加(4つのテスト)
docs/testing_strategy_phase3.md- キャッシュ機能に関する検証項目を追加
動作確認結果
静的解析結果
- ✅ リンターエラー: なし
実装確認項目
- キャッシュ層が実装されている
- 差分検出ロジックが実装されている
- 初回解析時に
.nexuscacheディレクトリが作られる - 2回目以降はキャッシュが使用される
- ファイル変更時は変更されたファイルだけ再解析される
- テストが追加されている
- ログ出力が実装されている
設計上の改善点
保守性の向上
- キャッシュ層の分離:
AnalyzerCacheクラスでキャッシュ管理を分離 - API 設計:
use_cacheパラメータでキャッシュを ON/OFF 可能 - 環境変数制御: デフォルト値を環境変数で制御可能
将来の拡張性への配慮
- バージョン管理: キャッシュフォーマットのバージョン管理により、将来の変更に対応可能
- graph_builder との整合性:
graph_builderを変更せずに統合可能 - 永続化: JSON ファイルによる軽量な永続化(将来的にデータベース化も可能)
コード品質の向上
- エラーハンドリング: キャッシュの読み込み/保存失敗時も処理を継続
- ログ出力: キャッシュヒット率などの統計情報をログ出力
- テスト: キャッシュ機能の包括的なテストを追加
既知の制約・注意事項
制限事項
- プロジェクト単位キャッシュ: キャッシュはプロジェクト単位で管理(プロジェクト間での共有はなし)
- ファイルパス: プロジェクト外のファイルはキャッシュしない
- ハッシュ計算: ファイル内容のハッシュ計算に失敗した場合は再解析
移行時の注意点
- 既存のコードはそのまま動作する(
TreeSitterEngineは変更なし) - キャッシュはデフォルトで有効だが、
use_cache=Falseで無効化可能 - キャッシュファイルは
.nexuscache/analyzer_cache.jsonに保存される
次のステップ
推奨されるフォローアップアクション
- インクリメンタル解析の改善: 依存関係を考慮したインクリメンタル解析
- キャッシュの最適化: 大きなプロジェクトでのキャッシュサイズ管理
- 分散キャッシュ: 複数マシン間でのキャッシュ共有
- キャッシュの有効期限: 一定期間経過後のキャッシュ無効化
まとめ
unified_analyzer にキャッシュ層を追加しました。以下の機能が追加・改善されました:
- ✅ キャッシュ層: プロジェクト単位でキャッシュを管理
- ✅ 差分検出: 変更のないファイルは再解析をスキップ
- ✅ 永続化:
.nexuscache/analyzer_cache.jsonに JSON 形式で保存 - ✅ API 設計:
use_cacheパラメータでキャッシュを ON/OFF 可能 - ✅ テスト: キャッシュ機能の包括的なテストを追加
- ✅ ログ出力: キャッシュヒット率などの統計情報をログ出力
- ✅ ドキュメント: テスト戦略ドキュメントにキャッシュ機能を追記
すべての実装は後方互換性を維持しており、既存のコードはそのまま動作します。キャッシュ機能により、同じプロジェクトを何度も解析する場合のパフォーマンスが大幅に改善されます。