Skip to content

perf(search): 検索の大文字小文字無視マッチに ASCII 高速パスを追加#440

Merged
kkyosuke merged 1 commit into
mainfrom
perf/search-ascii-fast-path
Jun 27, 2026
Merged

perf(search): 検索の大文字小文字無視マッチに ASCII 高速パスを追加#440
kkyosuke merged 1 commit into
mainfrom
perf/search-ascii-fast-path

Conversation

@kkyosuke

Copy link
Copy Markdown
Owner

目的

issue / memory のインクリメンタル検索のホットパスを軽くする。検索は入力1キーごとに再実行され、その都度すべての候補フィールド(title / body)を畳み込んでいたため、本レイヤで最も繰り返される文字列コストになっていた。

背景(性能レビューでの指摘)

matches_folded は候補フィールドごとに f.to_lowercase().contains(needle) を実行する。to_lowercase() は本文(数 KB に及びうる)の新規 String 確保 + Unicode 変換を伴い、N 件 × 毎キーストロークで O(全本文バイト数) を支払っていた。

変更内容

  • 畳み込みマッチを contains_folded(field, needle) に切り出した。
  • ASCII 高速パス: フィールドと needle の双方が ASCII のとき、確保なしのバイト単位の大文字小文字無視走査(windows + eq_ignore_ascii_case)で判定する。needlefold_query で既に小文字化済み。
  • フォールバック: いずれかが非 ASCII の場合は従来の to_lowercase().contains()。マルチバイト needle が文字境界をまたいで誤マッチしない性質(モジュールドキュメント参照)を維持する。

挙動は不変。

テスト・確認方法

  • cargo fmt / cargo clippy --all-targets -- -D warnings クリーン。
  • cargo test 全 2253 件 pass。ASCII 高速パス(needle がフィールドより長いケースを含む)と非 ASCII フォールバック(一致・不一致の両方)を網羅するテストを追加。
  • カバレッジ 100%(pre-commit ゲート通過)。

issue / memory 検索は入力1キーごとに再実行され、その都度すべての候補
フィールド(title / body)を `to_lowercase()` で畳み込んでいた。本文は
数 KB に及ぶことがあり、毎キーストロークで全件ぶんの新規 String 確保 +
Unicode 変換が走るのが本レイヤで最も繰り返されるコストだった。

`matches_folded` の畳み込みを `contains_folded` に切り出し、フィールドと
needle の双方が ASCII のときはバイト単位の大文字小文字無視走査(その場で
スキャン、確保なし)を行う高速パスを追加。いずれかが非 ASCII の場合は従来
どおり `to_lowercase().contains()` にフォールバックし、マルチバイトの
needle が文字境界をまたいで誤マッチしない性質を維持する。

挙動は不変。ASCII 高速パス(needle がフィールドより長い場合を含む)と
非 ASCII フォールバックの両経路を網羅するテストを追加。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

📊 Test Coverage

🚀 いまのカバレッジ (Lines): 100.00% — この調子でいこう!

🎉✨ パーフェクト!全ファイル Lines カバレッジ 100% を達成しました 🏆🐰

@kkyosuke kkyosuke merged commit 98df9a0 into main Jun 27, 2026
3 checks passed
@kkyosuke kkyosuke deleted the perf/search-ascii-fast-path branch June 27, 2026 20:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant