Rust Glancer: LSP Rust mới chỉ dùng dưới 100MB RAM

Mở một workspace Rust lớn trên máy 8GB RAM, rust-analyzer có thể ngốn vài GB chỉ để giữ autocomplete và jump-to-definition. Tuần này, một LSP thử nghiệm tên Rust Glancer ra mắt với lời hứa ngược lại: idle dưới 100MB.
Rust Glancer là dự án bốn tháng của một lập trình viên Rust khoảng 7 năm kinh nghiệm, từng đóng góp cho rustc, clippy và rust-analyzer. Bài giới thiệu "Hello, world!" công bố giữa tháng 8, nhanh chóng lên trang đầu Hacker News với hơn 400 điểm. Điểm gây chú ý không phải là một rust-analyzer "nhẹ hơn", mà là một cược kiến trúc đi ngược hoàn toàn với cách rust-analyzer đang chạy.
Vì sao rust-analyzer ngốn nhiều RAM
Có ba lý do chính, và không phải lý do nào cũng là lỗi thiết kế.
Thứ nhất, workspace Rust thật sự chứa nhiều thông tin cần index: hàng nghìn hàm, struct, trait, mối quan hệ giữa chúng, thân hàm và các câu lệnh bên trong. Muốn "find all references" chạy được, phải nhớ tất cả những thứ này ở đâu đó.
Thứ hai, rust-analyzer dùng salsa — một database truy vấn incremental. Cách tiếp cận này rất thông minh: thay vì "ghi sổ" mọi thứ một cách tường minh, nó lười biếng tính toán dữ liệu khi cần. Nhưng chính đặc tính đó khiến dữ liệu bị gắn chặt với bộ nhớ, khó chuyển bớt ra ngoài.
Thứ ba là rowan, thư viện biểu diễn cây cú pháp. Nó cho phép invalidate từng phần: chỉ sửa một đoạn file thì chỉ parse lại đúng đoạn đó, nhanh hơn nhiều so với parse lại cả file mỗi lần gõ. Đổi lại, cấu trúc cây bên trong gây phân mảnh bộ nhớ — nghĩa là RAM hệ điều hành cấp cho tiến trình nhiều hơn phần RAM thật sự được dùng.
Nói gọn: rust-analyzer chọn incremental và giữ-mọi-thứ-trong-RAM vì nó nhanh. Và nó đã thành công ở mục tiêu đó. Cái giá là bộ nhớ.
Cược ngược: workspace "đóng băng"
Tác giả Rust Glancer đặt một câu hỏi đơn giản: nếu không cần incremental thì sao? Thay vì một database cập nhật liên tục, toàn bộ kết quả phân tích trở thành một snapshot "đóng băng" (frozen), chỉ bị làm mới khi file được lưu.
Hệ quả trực tiếp: vì kết quả phân tích đã hoàn chỉnh, nó có thể được đẩy ra filesystem thay vì nằm trong RAM. Mỗi khi một query cần dữ liệu, server chỉ nạp phần liên quan trong đúng khoảng thời gian xử lý query đó, rồi thả ra. Idle RAM vì thế xuống rất thấp — theo tài liệu dự án, dưới 100MB kể cả với project lớn.
Cùng một quyết định đó mở ra lợi ích thứ hai: vì snapshot nằm trên đĩa, khi mở lại editor trên một project đã index xong, workspace hiện ra gần như tức thì. Không còn cảnh chờ re-index mỗi lần restart.
Để làm được điều này, Rust Glancer tái sử dụng syntax library của rust-analyzer (nhất là cho việc mở rộng macro), tích hợp chalk làm trait solver, và dùng jemalloc cho cả việc cấp phát lẫn profiling bộ nhớ. Một chi tiết đáng chú ý khác: tác giả công khai rằng dự án được viết với sự hỗ trợ nặng của LLM, nhưng dùng chúng như công cụ chứ không phải thay cho tư duy.
Cái giá phải trả
"Đóng băng" không miễn phí.
Query chậm hơn rust-analyzer trung bình. Đọc và deserialize dữ liệu từ đĩa luôn chậm hơn đọc từ bộ nhớ. Tác giả khẳng định độ trễ vẫn nằm trong vùng chấp nhận được — completion hiện ra trong hàng trăm mili giây, không phải hàng chục giây — nhưng đây là đánh giá chủ quan của một người đã quen dùng nó.
Việc index cũng chỉ chạy khi save. Trong lúc gõ, Rust Glancer dùng "shallow analysis" tái sử dụng index cũ, nghĩa là các mục mới (import, struct, trait) chưa được index cho đến khi bạn lưu file. Tác giả thừa nhận ban đầu nghe có vẻ đáng ngại, nhưng thực tế dùng lại thấy bình thường.
Và quan trọng nhất: đây chưa phải sản phẩm hoàn chỉnh. Proc macros chưa được hỗ trợ, type inference vẫn lỗi trong một số trường hợp, còn nhiều tính năng thiếu. Bản thân tác giả nói thẳng mục tiêu là "đủ 90%" — đủ dùng hằng ngày, không cố thành rust-analyzer 2.0.
Về benchmark, tác giả tự đo trên hai máy của mình: trên MacBook Pro M4 Max, Rust Glancer index đầy đủ mất 8 giây so với 13 giây của rust-analyzer; trên MacBook M1 8GB, con số là 9 giây so với 14 giây. Đây là số liệu mẫu nhỏ, một máy mỗi loại, nên chỉ nên đọc như tham chiếu ban đầu — không phải kết luận độc lập.
Điều cần biết
- Đây là câu chuyện kiến trúc, không phải câu chuyện "ai nhanh hơn". Rust Glancer đổi tốc độ lấy bộ nhớ. Nếu máy bạn dư RAM, rust-analyzer vẫn là lựa chọn mặc định an toàn.
- Incremental vs frozen là hai cực của một trục thiết kế. rust-analyzer tối ưu cho độ chính xác theo từng lần gõ phím; Rust Glancer tối ưu cho RAM thấp và restart nhanh. Không có bên nào thắng tuyệt đối.
- Máy yếu và luồng làm việc có AI agent là hai kịch bản đáng thử nhất. Tác giả nhắm tới máy 8GB và các luồng làm việc mà AI agent sửa code ngoài editor — nơi rust-analyzer dễ bị inlay hint lệch và re-index liên tục.
- Con số "100x less RAM" trong tiêu đề Hacker News là cách nói phóng đại. Con số thật của tác giả là idle dưới 100MB, đối chiếu với việc rust-analyzer có thể ngốn nhiều GB.
Rust Glancer còn non trẻ, chưa hoàn chỉnh, và có thể sẽ không bao giờ thay thế rust-analyzer. Nhưng giá trị thật của nó nằm ở chỗ nó chứng minh một giả định tưởng như hiển nhiên — "LSP thì phải incremental" — thực ra là một lựa chọn có thể đảo ngược. Khi RAM trở thành tài nguyên khan hiếm của máy yếu và của hạ tầng chạy agent, những lựa chọn như thế bắt đầu đáng giá.
Bài viết được hỗ trợ bởi AI (Amy 🌸). Nội dung đã được kiểm duyệt bởi tác giả.
Related Posts
GigaToken: Tokenizer Nhanh Gấp 1000 Lần — Điều Developer Cần Biết
Tokenizer LLM đạt 24.53 GB/s, nhanh gấp ~1000 lần HuggingFace và ~700 lần tiktoken. Viết bằng Rust, dùng SIMD. Không chỉ nhanh: nó thay đổi cách xử lý dữ liệu cho LLM.
Zerostack: AI Coding Agent Viết Bằng Rust, RAM 16MB Và Bài Học Về Hiệu Năng
Trong khi hầu hết AI coding agent ngốn 300-700MB RAM, Zerostack chỉ dùng 16MB. Viết bằng Rust, nặng 12.9MB binary — đây là cú hích vào giả định rằng AI tools phải nặng nề.
Bun Chuyển Sang Rust: Tại Sao Runtime JavaScript Nổi Tiếng Nhất Lại Bỏ Zig?
PR #30412 trên oven-sh/bun vừa được merge — Bun chính thức rewrite core từ Zig sang Rust. Binary nhỏ hơn 3-8MB, memory bugs giảm mạnh, và cộng đồng dev đang tranh luận dữ dội.