微软开源代码搜索工具 tgrep
[开源推荐] microsoft/tgrep 微软开源的命令行代码搜索工具:它把 grep/ripgrep 这类“每次查询都全量扫描”的工具,改造成“先建一次倒排索引,之后每次查询只碰可能匹配的文件...
微软开源的代码搜索工具,比传统 grep 快 50 倍,特别适合大型代码库和频繁查询场景。
微软开源了命令行代码搜索工具 tgrep,采用 trigram 倒排索引技术。在大型项目中,tgrep 最高比 ripgrep 快 50+ 倍,但需要约 20 分钟建索引和占用 2~4% 磁盘空间。tgrep 通过三层索引架构(磁盘索引、内存覆盖层、混合索引)实现高效搜索。
[开源推荐] microsoft/tgrep 微软开源的命令行代码搜索工具:它把 grep/ripgrep 这类“每次查询都全量扫描”的工具,改造成“先建一次倒排索引,之后每次查询只碰可能匹配的文件...
[开源推荐] microsoft/tgrep 微软开源的命令行代码搜索工具:它把 grep/ripgrep 这类“每次查询都全量扫描”的工具,改造成“先建一次倒排索引,之后每次查询只碰可能匹配的文件”。在大型项目中,最高比 ripgrep 快 50+ 倍! github.com/microsoft/tgrep 核心思想:把复杂度从“每次查询”挪到“一次性建索引” 传统 grep/ripgrep 的每次查询是 O(全库字节)。这在 30 万~50 万文件的 monorepo(Chromium、gecko-dev 这个量级)上意味着单次搜索几秒到几十秒。tgrep 的做法是经典的 trigram 倒排索引——这正是 Google 早期代码搜索(Russ Cox 的 codesearch)的思路: 1. 索引阶段:把每个文件的字节流切分成所有重叠的 3 字节 trigram,构建“trigram → 文件列表”的倒排索引。 2. 查询阶段:用 regex-syntax 解析正则,提取其中的字面量片段(literal extraction),把片段转成 trigram 集合;对 posting list 做交集(AND)或并集(OR),得到候选文件集;最后只对候选文件用完整正则引擎做并行验证。 结果就是:搜索只读极少数文件。代价是约 20 分钟一次的建索引(Chromium 级别)和约等于语料 2~4% 的磁盘索引。 架构:常驻服务器 + 三层索引 tgrep <pattern> - TCP/JSON-RPC -> tgrep serve -> HybridIndex · IndexReader:mmap 磁盘索引,零拷贝,在有序 trigram 查找表上二分查找。 · LiveIndex:内存覆盖层,存放服务器启动后新增/修改的文件,优先级高于磁盘索引。 · HybridIndex:合并两者,对客户端呈现统一视图。 · 后台索引器:rayon 并行建索引(每批 500 文件),建到一半就能查询——服务器先起,从部分数据开始服务。 · 文件监听:notify crate 实时捕获变更更新 LiveIndex,每小时做一次对账防止漏事件;每 5 万文件或 5 分钟刷盘一次。 · TCP 服务器:JSON-RPC 2.0 over 换行分隔 TCP,每连接一线程,多客户端并发;客户端通过 serve.json 里的 PID/端口自动发现服务器。 工程质量:一线工程判断细节 · 内存控制:默认采用外部归并排序建索引,峰值内存基本不随仓库增长(Linux 内核上约 150 MiB,相比内存策略的 2.2~3.8 GiB 降了 ~17 倍,且不牺牲时间)。 · 诚实的内存度量:曾有人在 29 万文件 monorepo 上报出 13.49 GiB 峰值,排查后发现是工作集指标把 mmap 的文件页算进去了(一个 2 GiB 文件让真实私有内存被夸大 26 倍)——于是改为报告 private bytes。这种“先搞清楚指标再优化”的态度很少见。 · 64 MiB 文件大小上限:一个真实案例中,某个 13.41 GiB 的生成产物占了语料的 71%,设上限后热查询从 21.3s 降到 0.55s。且命令行显式指定的文件不受上限影响,--no-max-filesize 可完全关闭。 · ripgrep 兼容性作为采用策略:绝大多数 rg 旗标可用或被无害忽略(--mmap、--crlf),退出码一致,输出兼容 rg 的 JSON 格式——用户可以无痛把脚本里的 rg 换成 tgrep。而 -z(压缩文件搜索)故意以错误码 2 退出而非静默返回空结果,避免“看起来搜完了其实没搜”。 · UTF-8 处理:无效字节用 U+FFFD 替换后进 trigram 索引,位置再映射回真实字节偏移,保证 --column、--vimgrep 等输出正确。 · 真实世界适配:支持 P4 ignore 文件、无 .git 但有 .gitignore 的 Perforce 场景、Windows 大小写不敏感文件系统(读取 git 的 core.ignorecase 来匹配忽略规则)。 它不是 ripgrep 的全面替代品,有明确适用边界的工具: · 适合:10 万文件以上的大仓库、Windows/macOS 开发环境、Coding Agents 这类高频低延迟 grep 场景、一次性探索性查询多的日常工作流。 · 不适合/代价:需要一次性建索引的时间和磁盘(Chromium 约 1 分钟 + 2.5 GB 索引);小仓库收益有限;搜索高频 token 时可能更慢;极端冷启动下服务器就绪需约 30 秒(内核仓库)。 💬 0 🔄 0 ❤️ 1 👀 247 ⚡