コードベースやナレッジベースの拡大に伴い、全文検索エンジンの実行レイテンシは開発者および AI エージェントの自律ワークフローにおける主要なボトルネックとなる。
本稿では、Trigram(3-gram)転置インデックスを活用した超高速正規表現検索ツール tgrep(バージョン 1.0.4.0)をワークスペースに導入し、業界標準の ripgrep (rg)(バージョン 15.1.0)との間で、実環境(ObsidianVault 1,282 ファイル、および Projects/pi 1,633 ファイル)を用いた機能・性能の網羅的比較ベンチマークを実施した。
さらに、インメモリ全文検索(Obsidian Smart Search Plugin)との比較を通じ、「動的に更新されるナレッジベース」 と 「静的で巨大なコードベース」 における検索エンジンの最適な適材適所の設計論を体系化する。
graph TD
subgraph Ripgrep ["ripgrep (オンデマンド全走査型 / Brute-force SIMD)"]
RG_IN["検索クエリ"] --> RG_DIR["全ディレクトリ走査 (NTFS/I/O)"]
RG_DIR --> RG_PARSE["全ファイル読み込み & Rust Regex エンジン"]
RG_PARSE --> RG_OUT["マッチ結果出力 (毎クエリ 70〜120ms)"]
end
subgraph Tgrep ["tgrep (Trigram 転置インデックス型 / Zoekt・Google CodeSearch 思想)"]
TG_INDEX["事前インデックス構築 (.tgrep / 3-gram 転置リスト)"]
TG_IN["検索クエリ"] --> TG_FILTER["クエリの Trigram から候補ファイルを O(1) 絞り込み"]
TG_FILTER --> TG_PINPOINT["対象ファイルのみをメモリ精査"]
TG_PINPOINT --> TG_OUT["マッチ結果出力 (毎クエリ 15〜35ms)"]
end
subgraph SmartSearch ["Obsidian Smart Search (インメモリ cachedRead 型)"]
SS_MEM["Obsidian 起動時に全ノートを RAM に保持 (cachedRead)"]
SS_IN["検索クエリ (UI)"] --> SS_SCAN["純粋 JS/TS でプロセス外呼出なしに即時スキャン"]
SS_SCAN --> SS_OUT["マッチ結果出力 (0〜5ms / プロセス生成コスト 0)"]
end
| 比較軸 | ripgrep (rg) |
tgrep |
Obsidian Smart Search |
|---|---|---|---|
| アーキテクチャ | ディスク直接走査 + SIMD 並列処理 | Trigram (3-gram) 転置インデックス | RAM 常駐型インメモリ走査 |
| 事前準備 | 不要(ゼロ・セットアップ) | 必要 (tgrep index) |
初回起動時の自動読み込み |
| CLI 互換性 | 業界デファクト標準 | ripgrep 完全互換レベル | なし(Obsidian プラグイン内部 API) |
| 検索レイテンシ | 70 〜 120 ms | 15 〜 35 ms (2〜4倍高速) | 0 〜 5 ms (プロセス起動オーバーヘッドなし) |
| ファイル更新の追従 | 即時・100% 整合 | インデックス再作成または serve 常駐が必要 |
即時・100% 整合 (app.vault イベント連動) |
| 得意な対象 | 中小〜大規模の任意のディレクトリ | 超巨大・静的なコードベース (Projects) | 頻繁に書き換わる個人 Vault ノート |
- 検証環境: Windows 11, AMD/Intel Multi-core, NVMe SSD
- 対象データ:
ObsidianVault(テキストファイル 1,282 件、バイナリ 717 件、総行数 40万行超) - 試行回数: 各ケース Warm-up 1回 + 5回計測の平均値
| テストケース | 検索クエリ | ripgrep (rg) |
tgrep (インデックス) | tgrep (no-index) | 高速化倍率 | マッチ行数 (rg / tg) |
|---|---|---|---|---|---|---|
| 完全一致英単語 | Zettelkasten |
70.3 ms | 16.1 ms | 128.4 ms | 4.36倍 高速 | 29 / 29 (完全一致) |
| 日本語ロング複合語 | 構造認識型情報検索 |
80.0 ms | 18.2 ms | 143.8 ms | 4.39倍 高速 | 6 / 6 (完全一致) |
| 正規表現パターン | \[2609\.\d{5}\] |
82.3 ms | 21.3 ms | 143.0 ms | 3.86倍 高速 | 15 / 15 (完全一致) |
| ゼロヒット単語 | NonExistentKeywordXYZ... |
117.5 ms | 31.5 ms | 184.1 ms | 3.73倍 高速 | 0 / 0 (完全一致) |
| 大文字小文字無視 (複合) | -i knowledge graph |
78.6 ms | 36.0 ms | 146.3 ms | 2.18倍 高速 | 289 / 289 (完全一致) |
| 日本語キーワード | エージェント・ハーネス |
78.7 ms | 36.9 ms | 147.6 ms | 2.13倍 高速 | 102 / 102 (完全一致) |
| 超高頻度単語 | Obsidian |
115.7 ms | 75.1 ms | 308.7 ms | 1.54倍 高速 | 579 / 579 (完全一致) |
- 信頼性 (Recall / Precision) の完全性: 全テストケースにおいて、ripgrep と tgrep の出力行数は 1行の誤差もなく 100% 完全一致 した。Trigram 枝刈りによる取りこぼし(偽陰性)は一切発生しない。
- 選択性の高いクエリでの爆発的な高速化:
出現頻度が限られる特定の技術用語(
Zettelkasten,構造認識型情報検索等)や正規表現では、Trigram フィルターが事前に 99% 以上のファイルを候補から除外するため、4.3倍以上の高速化(16〜18ms) を達成した。 - ゼロマッチ時の高速性: 該当データが存在しない場合、ripgrep は全 1,282 ファイルの全行を走査するため最長(117.5ms)を要するが、tgrep は Trigram 転置テーブルの交差判定時点で「該当ファイルゼロ」を即座に判定できるため、31.5ms(3.7倍高速) で処理を完了する。
tgrep index の処理性能とリソース消費の実測値:
| 測定項目 | ObsidianVault (ドキュメント) |
Projects/pi (TypeScript モノレポ) |
|---|---|---|
| 対象テキストファイル数 | 1,282 件 | 1,633 件 (純粋コード 約28万行) |
| 除外バイナリファイル | 717 件 | 13 件 |
| 抽出 Trigram 総数 | 239,998 | 204,874 |
| インデックス作成所要時間 | 3.2 秒 | 4.7 秒 |
| ピークメモリ消費 | 121.6 MiB | 94.9 MiB |
| 生成インデックスサイズ | 約 32.2 MB (.tgrep) |
約 28.5 MB (.tgrep) |
ファイルカウント速度 (count-files) |
29 ms | 101 ms |
1,000〜2,000ファイル規模のコードベースであれば、わずか 3〜5 秒・100MB 程度のメモリ でインデックスが生成されるため、ローカルマシンにおける構築負荷は極めて小さい。
Obsidian 内部での日常検索において、ユーザーが指摘した通り tgrep の優位性は限定的 である。その理由は以下のアーキテクチャ的要因に帰着する。
- プロセス起動コストの壁 (Process Spawn Cost):
Windows 環境において外部バイナリ(
tgrep.exeやrg.exe)を別プロセスとして生成するだけで 10〜15ms の OS レベルの固定レイテンシが発生する。 Obsidian Smart Search プラグインはapp.vault.cachedReadを用いて全ファイルをすでに Node.js/Electron のヒープメモリ(RAM)上にキャッシュしているため、プロセス生成コストが完全に 0ms であり、数千件の検索を 0〜5ms で完了できる。 - インデックスの鮮度問題 (Cache Invalidation & Staleness):
Obsidian のノートは、ユーザーの手動編集、Web クライッピング、arXiv の自動要約、デイリーノート生成などによって 1日に数十回以上、動的に作成・更新 される。
tgrepは静的インデックスであるため、編集直後にtgrep indexを再実行しない限り、新しく書いた内容が検索にヒットしない(検索漏れのリスク)。 これを解決するために常駐デーモン(tgrep serve)を起動し続けるアプローチもあるが、個人用ノート環境においてバックグラウンドメモリを常時 100〜200MB 占有させるのはアーキテクチャとして過剰設計(Over-engineering)となる。
tgrep の真価は、「手元で頻繁に更新しないが、検索回数が極めて多い巨大なコードベースやアーカイブ」 で発揮される。
- 巨大な外部クローンリポジトリ (
Projects/pi, Linux, Chromium, LLM SDKs 等):- 自身で頻繁にコードを編集しない参照用リポジトリ。
- ファイル数が数万〜数十万行に達する場合、ripgrep のオンデマンド全走査は 500ms〜数秒に達するが、
tgrepなら 10〜30ms を常に維持できる。 - AI コーディングエージェントが「関数の参照箇所」「型定義」「エラーメッセージ」を反復的に探索する際、エージェントの思考ループ速度を劇的に引き上げる。
- 静的ドキュメント・規格書・ログアーカイブ:
- RFC、仕様書、過去のログファイルなど、内容が不変(Immutable)なデータセットに対する検索基盤。
| 検索対象領域 | 推奨エンジン | 選定理由 |
|---|---|---|
| Obsidian Vault (日常検索・UI) | Obsidian Smart Search | RAM常駐によりプロセス起動コストゼロ (0〜5ms)、ファイル更新への即時自動追従。 |
| Obsidian Vault (CLI / スクリプト) | ripgrep (rg) |
インデックスの事前生成や鮮度管理が不要。全走査でも 70〜100ms で十分実用的。 |
巨大リポジトリ (Projects/pi 等) |
tgrep |
Trigram インデックスにより、大規模コードベースでも 15〜30ms で超高速応答。エージェントの検索性能を最大化。 |
| AST 認識・構文解析探索 | ast-digger |
関数・クラス・Mermaid・見出し階層など、構文木に沿ったピンポイント抽出。 |
- [[検索技術選定ガイド (HyDE vs BM25 vs ripgrep vs ast-digger)]]
- [[mdsearchにおけるベクトル類似度検索の現状と改善アプローチ]]
- [[Pi]]
- [[エージェント・ハーネスのモデル癒着とポータビリティ担保の設計論]]
- Google Code Search (Russ Cox - Regular Expression Matching with a Trigram Index)