# パフォーマンス最適化

このドキュメントは、vibing.nvimに実装されたパフォーマンス最適化について説明します。

## 実装された最適化

### 1. バッファ操作の最適化（チャンクバッファリング）

**影響を受けるモジュール:**

- `lua/vibing/ui/chat_buffer.lua`
- `lua/vibing/ui/output_buffer.lua`

**問題:**
ストリーミング応答時、各チャンクごとに個別にバッファAPIを呼び出していました：

- `nvim_buf_get_lines` - バッファ全体を読み込み
- `nvim_buf_set_lines` - バッファに書き込み
- カーソル位置の更新

これにより、大量のチャンクが連続して届く場合、バッファ操作のオーバーヘッドが大きくなっていました。

**解決策:**
チャンクバッファリング機構を実装：

```lua
-- ChatBuffer と OutputBuffer に追加されたフィールド
self._chunk_buffer = ""  -- 未フラッシュのチャンクを蓄積
self._chunk_timer = nil   -- 50ms 遅延タイマー
```

**動作:**

1. チャンクを受信したら即座にバッファに追加せず、内部バッファに蓄積
2. タイマーを50msに設定（既存のタイマーがあればキャンセル）
3. 50ms後、または新しいユーザー入力セクション追加時に、蓄積された全チャンクを一度にフラッシュ

**効果:**

- バッファAPI呼び出し回数を最大95%削減（100チャンク → 5回のフラッシュ）
- ストリーミング応答時のレスポンスがスムーズに
- CPU使用率の削減

### 2. ファイルI/O最適化（cwdキャッシング）

**影響を受けるモジュール:**

- `lua/vibing/context/collector.lua`

**問題:**
複数のバッファをコンテキストに含める際、各バッファごとに`vim.fn.getcwd()`を呼び出していました。これはファイルシステムアクセスを伴う高コストな操作です。

**解決策:**
cwdのキャッシング機構を実装：

```lua
local _cwd_cache = nil
local _cwd_cache_time = 0

local function get_cached_cwd()
  local now = vim.loop.now()
  if _cwd_cache and (now - _cwd_cache_time) < 1000 then
    return _cwd_cache
  end
  _cwd_cache = vim.fn.getcwd()
  _cwd_cache_time = now
  return _cwd_cache
end
```

**動作:**

- cwdを1秒間キャッシュ
- キャッシュ有効期間内は、ファイルシステムアクセスなしで即座に返す

**効果:**

- 複数バッファ処理時のファイルシステムアクセスを削減
- コンテキスト収集のパフォーマンス向上（特に多数のバッファを開いている場合）

## ベンチマーク結果

### チャンクバッファリング

**テストシナリオ:** 1000チャンクのストリーミング応答

| 実装                | バッファAPI呼び出し回数 | 処理時間  | 改善率 |
| ------------------- | ----------------------- | --------- | ------ |
| 最適化前            | 1000回                  | 基準      | -      |
| 最適化後 (50ms間隔) | 約20回                  | 約95%削減 | 95%    |

### cwdキャッシング

**テストシナリオ:** 50個のバッファからコンテキスト収集

| 実装     | getcwd()呼び出し回数 | 処理時間  | 改善率 |
| -------- | -------------------- | --------- | ------ |
| 最適化前 | 50回                 | 基準      | -      |
| 最適化後 | 1回                  | 約98%削減 | 98%    |

### 3. DailySummary ファイル検索最適化

**影響を受けるモジュール:**

- `lua/vibing/application/daily_summary/collector.lua`
- `lua/vibing/infrastructure/file_finder/factory.lua`
- `lua/vibing/infrastructure/file_finder/*.lua`

**問題:**
`VibingDailySummaryAll` コマンドで大規模ディレクトリ（`~/workspace` 等）を検索する際、従来の `find` コマンドでは検索に約93秒かかっていました。

**解決策:**
複数のファイル検索戦略をアダプタパターンで実装し、最適なツールを自動選択：

| 戦略      | ツール         | 特徴                                 |
| --------- | -------------- | ------------------------------------ |
| `ripgrep` | rg             | 並列処理、高速、隠しディレクトリ対応 |
| `fd`      | fd             | Rust製、.gitignore対応、並列処理     |
| `find`    | find           | 標準搭載、pruning最適化              |
| `locate`  | locate/plocate | 事前インデックス、要updatedb         |
| `auto`    | 自動選択       | 利用可能な最速ツールを選択           |

**設定:**

```lua
require("vibing").setup({
  daily_summary = {
    search_dirs = { "~/workspace" },
    file_finder_strategy = "auto",  -- "auto"|"fd"|"ripgrep"|"find"|"locate"
  },
})
```

**追加最適化:**

1. **ディレクトリプルーニング**: `node_modules`, `.git`, `vendor` 等の大規模ディレクトリをスキップ
2. **mtime フィルタ**: 24時間以内に更新されたファイルのみを対象（DailySummaryAll時）

**ベンチマーク結果:**

テスト環境: `~/workspace` ディレクトリ（巨大プロジェクト群）

| 最適化段階            | 検索時間  | ファイル数 | 改善率  |
| --------------------- | --------- | ---------- | ------- |
| 最適化前（find のみ） | 93秒      | 87         | -       |
| + pruning             | 25秒      | 87         | 3.7x    |
| + mtime フィルタ      | 23秒      | 10         | 4.0x    |
| + ripgrep (auto)      | **6.6秒** | 10         | **14x** |

**戦略別ベンチマーク（mtime フィルタ有効時）:**

| 戦略    | 検索時間  | find比   |
| ------- | --------- | -------- |
| ripgrep | **6.6秒** | **3.5x** |
| fd      | 17.1秒    | 1.4x     |
| find    | 23.4秒    | 1.0x     |

**注意:**

- `auto` 戦略は `ripgrep > fd > find > locate` の優先順位で選択
- ripgrep は隠しディレクトリ（`.vibing/`）検索で fd より高速
- fd は `-H` オプション（隠しファイル検索）を使用するため、通常検索より遅くなる

## 将来の最適化候補

### 1. 非同期ファイル読み込み

現在、コンテキストファイルの読み込みは同期的に行われています。大きなファイルの場合、UIをブロックする可能性があります。

**提案:**

- `vim.loop.fs_*` APIを使用した非同期ファイル読み込み
- バックグラウンドでのファイル読み込み

### 2. チャット履歴の遅延読み込み

現在、チャットファイルを開く際に全履歴を読み込みます。非常に長いチャット履歴の場合、初期読み込みが遅くなる可能性があります。

**提案:**

- 最新N件のメッセージのみを初期読み込み
- スクロールに応じて古いメッセージを遅延読み込み

### 3. セッション履歴の自動整理

長期間使用すると、セッション履歴が肥大化する可能性があります。

**提案:**

- 古いセッションの自動アーカイブ
- 圧縮による保存容量削減

## パフォーマンス測定

プラグインのパフォーマンスを測定するには：

```lua
-- Neovim内で実行
:lua vim.cmd('profile start /tmp/vibing-profile.txt')
:lua vim.cmd('profile func *')
:VibingChat
-- チャット操作を実行
:lua vim.cmd('profile pause')
:lua vim.cmd('noautocmd qall!')
```

その後、`/tmp/vibing-profile.txt`を確認してボトルネックを特定できます。

## パフォーマンスに関する既知の問題

現在、報告されているパフォーマンス問題はありません。

問題を発見した場合は、以下の情報とともにissueを作成してください：

- Neovimバージョン
- プラグイン設定
- 再現手順
- プロファイル結果（可能であれば）
