一个 4 个月的业余项目,把 Rust LSP 的内存砍掉两个数量级
一个 4 个月的业余项目,把 Rust LSP 的内存砍掉两个数量级
你的 8GB MacBook 是不是一开 Rust 项目就风扇狂转?rust-analyzer 索引跑完,内存直接吃掉两三个 GB,Chrome 都跟着遭殃。这事大家忍了很多年,抱怨归抱怨,没人真去解决。
直到有人花了 4 个月,自己写了一个。
数字先摆出来
Rust Glancer,一个作者用 4 个月从零写的 rust-analyzer 替代品,目标很朴素:语言服务器内存压到 100MB 以下。
实测数据(作者自己跑的):
- 8GB M1 MacBook Pro(2020):全量索引 9 秒,rust-analyzer 要 14 秒;全程内存 <100MB
- M4 Max 36GB:索引 8 秒 vs 13 秒
不是"更省",是省了整整两个数量级。这项目在 Hacker News 拿了 392 分,最重的背书来自 matklad——rust-analyzer 作者本人。他写了篇评论文章,原话是"incredibly cool"。顺便还承认了自己项目里一个扎心的事实:rowan 语法树"是垃圾"(原文 "rowan is garbage :P")。
核心思路:不做增量,冻结分析
rust-analyzer 内存大的根子,作者拆成三条:
- Rust workspace 的信息量本来就大,这个绕不开
- salsa 增量查询数据库——很酷,但数据天生绑死在内存里
- rowan 语法树——为了局部失效(改一行只重解析一行)付出了内存碎片化的代价
Glancer 的选择是全部推翻:不做增量计算,只有一个"冻结的分析结果,保存时整体失效"。
听起来像是退化,但它换来两个特性:
- 分析结果可以卸载到文件系统,查询时按需加载
- 重启编辑器不需要重新索引——结果已经在磁盘上了
类比一下:rust-analyzer 是图书馆把全部藏书摊在桌上随时翻;Glancer 是书都放回书架,你要哪本现取哪本。慢一点点,但桌子(内存)永远清爽。
打字时的处理也聪明:不做全量分析,只对当前函数体做浅层分析,复用之前的完整索引。代价是新增的 import、结构体、trait 要等你保存后才进索引。
matklad 自己承认:为 1% 的场景牺牲了 99%
matklad 的评论比背书更值得读。他说 rowan 设计目标是增量解析和 DOM 式重构,"但那只是 1% 的用例。99% 的用例是你那 6666 个依赖——你永远不会看它们,但它们至少要被浅层分析一遍。"
他还画了个更大的饼:IntelliJ 的 PSI 是接口,不是实现。编辑器里打开的文件用具体语法树,其余项目文件用紧凑的 stub tree(不含函数体),依赖直接用编译产物 .rmeta。rust-analyzer 应该只在你真的开始翻 ~/.cargo/registry 时才切换到完整分析。
这套"冰山架构"——增量分析只覆盖尖顶,其余大部分是只读的、磁盘上的、紧凑的——目前没人做完。Glancer 算是往这个方向走了一步。
别急着卸载 rust-analyzer
得泼盆冷水。Glancer 还不是完整的 LSP:功能有缺口,有已知 bug,proc macro 支持这类硬骨头基本别指望。作者自己说得很明白:"Glancer 永远不会变成'像 rust-analyzer 一样,但更好'"。它适合的是内存紧张的人、愿意为省内存做点牺牲的人。
对 agentic workflow 倒是有个意外加成:它实现了自定义文件 watcher,编辑器外的改动优先级低。agent 批量改代码时不会触发疯狂重索引,inlay hints 也不会错位——rust-analyzer 反而有这毛病。
你今天可以做的事
- 8GB 机器写 Rust:装 VS Code 扩展试一下,不好用再卸,成本五分钟
- 内存不是问题:把"冻结分析 + 按需加载"这个思路记下来——任何吃内存的索引工具(语言服务器、CI 缓存、搜索索引)都能借鉴
- 闲了读一遍 matklad 的评论原文,那是教科书级的架构复盘
✨ 本文由 DeepSeek 生成初稿,Claude 审核润色。
参考来源: