不是「換成 Rust 就變快」,而是重新定義要服務誰
ast-grep 團隊把 Tree-sitter 的 C 核心改寫成 Rust,解析吞吐量提高 29.74%,但這個醒目的「快 30%」只涵蓋解析器;放進 ast-grep 的完整 outline 工作負載後,使用者 CPU 時間由 1.233 秒降至 0.960 秒,改善 22.2%,尖峰常駐記憶體則由 26.52 MiB 增至 34.43 MiB,增加 29.8%。這些數字均來自團隊自己的測試,而非第三方基準。原始報告:https://astgrep.com/blog/tree-sitter-rust-rewrite
來源事實:Tree-sitter 是產生具體語法樹(CST)的解析器框架;ast-grep 會先將程式碼解析成樹,再依結構而非純文字進行搜尋與改寫。ast-grep 官方文件也確認,其底層使用 Tree-sitter,且實際比對的是保留標點等細節的 CST:https://ast-grep.github.io/advanced/core-concepts.html
因此,解析不是可有可無的前處理,而是每個檔案都要支付的固定成本。當規則比對、快取與樹剪枝已陸續最佳化,底層解析器自然成為新的效能上限。
效能從哪裡來:少做事,比換語言更關鍵
Tree-sitter 面對有歧義的程式語法時,可讓解析歷程分叉,再共享共同狀態。原文指出,觀察到的解析堆疊約有 99% 只是單一路徑,因此新版先走線性堆疊,直到真的遇到歧義才建立完整圖狀結構。內部節點則改由 arena 集中配置,並縮小索引;常用文法查詢預先準備,ASCII 與單一解析動作另設快速路徑;讀取完成後的樹時,也避免重複查找同一組子節點。
合理推論:主要收益不能簡化為 Rust 的語言優勢。真正改變的是資料布局、配置策略與常見路徑;更重要的是,團隊刪除了增量舊樹重用,以及原生載入 WebAssembly 文法的能力。這是一套針對「一次讀取完整檔案」的特化 runtime,而不是上游 Tree-sitter 的等價替代品。
這項界線可由雙方第一方資料交叉驗證。上游 Tree-sitter 將自己定位為增量解析函式庫,目標包括在文字編輯器每次按鍵時快速更新語法樹,且核心 runtime 為 C11:https://tree-sitter.github.io/tree-sitter/;相對地,改寫版公開程式庫明載每次解析都從完整輸入建立新的 CST:https://github.com/HerringtonDarkholme/tree-sitter
相容性才是這次重寫的商業邏輯
團隊沒有要求既有文法重新產生,而是保留 C ABI、公開函式、資料布局與呼叫慣例,讓現成文法表及外部 scanner 繼續使用。這等於把改寫範圍藏在既有介面後方:內部可以逐步換掉,外部生態系不必同步遷移。對工具產品而言,這往往比追求完全「純 Rust」更有價值,因為真正昂貴的是破壞相容性後的整體轉換成本。
代價是邊界仍保留大量 raw pointer 與 unsafe。因此,這也不是「改用 Rust 即自動消除記憶體風險」的案例;Rust 提供了較能局部推理的內部結構,但 ABI 相容層仍須靠測試、審查與不變條件守住。
為何現在值得注意:AI 降低了嘗試成本,沒有降低驗證成本
程式翻譯、效能分析工具、實驗性修改與不少實作由 ChatGPT 在作者指導下完成。第一次要求提升 20% 效能時,雖然局部基準達標,程式卻難以理解且出現 segmentation fault,最後整批撤回。之後流程改成一次處理一個機制,以 profile 找熱點,和前一版比較,再測完整應用。
作者觀點:這比「AI 能否重寫大型系統」更有啟發性。AI 確實讓單一開發者能探索過去不敢碰的核心元件,但同時放大了產生大量合理外觀程式碼的能力。工程瓶頸因而從「寫不寫得出來」移向「能否設計正確的驗證邊界」。
最容易忽略的限制
- 30% 是解析吞吐量,不是所有 ast-grep 操作都會固定快 30%;完整 outline 的指標是少 22.2% 使用者 CPU。
- 成果是團隊自測。這篇總覽未在數字旁完整提供硬體、編譯旗標、重複次數及誤差範圍,不能直接外推到其他處理器、語言組合或儲存環境。
- 完整工作負載多用約 8 MiB,尖峰 RSS 增加近三成;在單機命令列或許可接受,在高併發服務與記憶體受限的 CI runner 上則可能抵銷吞吐收益。
- 這個分支不重用舊樹,不能以目前結果推論編輯器、IDE 或需要連續小幅更新的場景也會受益。
對台灣開發團隊的實際意義
對使用 monorepo、程式碼掃描、CI 靜態檢查、跨語言重構或 AI coding agent 的團隊,這項成果提供了一個可採用的判準:若工作負載本來就是逐檔讀取完整快照,犧牲增量解析換取較快批次處理,可能合理;若產品核心是 IDE、即時語法標示或長駐服務,就不能只看解析吞吐量。
更普遍的教訓,是重寫基礎元件前先盤點「哪些相容性是客戶真正依賴的、哪些功能只是歷史包袱」。保留 ABI 與既有文法生態、縮窄 runtime 用途,才是這次改寫能落地的關鍵;Rust 與 AI 都是手段。
後續應觀察什麼
- 是否公布可重現的 benchmark 腳本、固定版本、硬體環境及統計分布。
- 在不同語言、超大型檔案、多 worker 與受限記憶體環境下,CPU/RSS 交換是否仍划算。
- 既有文法、外部 scanner、錯誤復原與 ABI 相容性,能否經長期實際使用維持。
- 改寫版會成為 ast-grep 專用分支、可重用的 agent runtime,還是逐步與上游技術交流。
這次最值得記住的不是「Rust 比 C 快 30%」,而是局部勝利曾讓完整應用變慢,arena 也一度把壓力測試推到 1.04 GiB。最後的進步來自把解析、配置、樹遍歷與應用生命週期放回同一張帳本。真正可靠的最佳化,必須在使用者實際付費的邊界上成立。