# LLM 寫了 57 萬行 Rust 程式,編譯成功,比 SQLite 慢 20,171 倍 > Author: Tony Lee > Published: 2026-03-12 > URL: https://tonylee.im/zh-HK/blog/llm-570k-lines-rust-sqlite-plausible-code-trap/ > Reading time: 2 minutes > Language: zh-HK > Tags: ai, code-review, llm, rust, benchmarking, software-engineering ## Canonical https://tonylee.im/zh-HK/blog/llm-570k-lines-rust-sqlite-plausible-code-trap/ ## Rollout Alternates en: https://tonylee.im/en/blog/llm-570k-lines-rust-sqlite-plausible-code-trap/ ko: https://tonylee.im/ko/blog/llm-570k-lines-rust-sqlite-plausible-code-trap/ ja: https://tonylee.im/ja/blog/llm-570k-lines-rust-sqlite-plausible-code-trap/ zh-CN: https://tonylee.im/zh-CN/blog/llm-570k-lines-rust-sqlite-plausible-code-trap/ zh-TW: https://tonylee.im/zh-TW/blog/llm-570k-lines-rust-sqlite-plausible-code-trap/ ## Description 有人對 LLM 用 Rust 重寫的 SQLite 進行基準測試。結果揭示了「看起來正確的程式碼」與「真正正確的程式碼」之間,可以相差五個數量級。 ## Summary LLM 寫了 57 萬行 Rust 程式,編譯成功,比 SQLite 慢 20,171 倍 is part of Tony Lee's ongoing coverage of AI agents, developer tools, startup strategy, and AI industry shifts. ## Outline - B-tree 存在,但 query planner 完全無視它 - 安全預設值像複利一樣疊加 - 用 82,000 行程式碼取代一個 cron 單行指令 - 研究數據指向同一個方向 - 這對開發者的真正要求是什麼 ## Content 有人用 LLM 全程生成了一個 Rust 版本的 SQLite 重寫項目,並對它進行基準測試。程式碼能編譯。測試全部通過。程式碼乾淨、結構清晰、符合慣用 Rust 風格。但在最基本的 primary key 查詢上,它比 SQLite 慢了 20,171 倍。 這個數字讓我停下來想了很久。不是因為 LLM 生成的程式碼跑得慢令人意外,而是因為慢的根源所在。這些程式碼並沒有任何編譯器或測試套件能捕捉到的錯誤。B-tree 實作是正確的。Query planner 存在。Storage engine 能運作。每個部分單獨看都站得住腳。但整個系統合在一起,幾乎無法使用。 我花了時間細讀基準測試分析和原始碼。當中發現的模式在 LLM 生成的項目中反覆出現,我認為這些模式指向了這類模型寫程式碼的某個根本性問題。 ## B-tree 存在,但 query planner 完全無視它 在 SQLite 裡,PRIMARY KEY 查詢會走 B-tree 路徑,以 O(log n) 的時間完成。`where.c` 裡四行程式碼負責檢查 iPKey 並將查詢直接導向 B-tree。這類微優化只有在你理解整個系統如何協同運作時,才能做到。 LLM 生成的版本也有 B-tree 實作,而且在獨立測試時運作正確。問題在於 query planner 在處理 primary key 查詢時,從來不調用它。`is_rowid_ref()` 函式只識別三個字面字符串:"rowid"、"_rowid_" 和 "oid"。如果你宣告了一個 `id INTEGER PRIMARY KEY` 的欄位,planner 並不會將它識別為 rowid 的別名。每一個查詢都走了全表掃描。 這裡的數字很殘酷。對 100 行資料查詢 100 次,B-tree 路徑大約需要 700 步比較。全表掃描路徑則超過 10,000 步。但真正的傷害來自算法複雜度的差異:每次查詢從 O(log n) 變成 O(n),在整個基準測試套件中累積下來,就造成了 20,171 倍的差距。 這類 bug 沒有任何 unit test 能捕捉到,除非你專門寫基準測試。B-tree 能用。全表掃描也能用。Planner 只是選錯了路徑。一切都通過測試。 ## 安全預設值像複利一樣疊加 這個案例比單純的路由 bug 更有意思的地方,正在這裡。即使修正了 query planner 的問題,這個重寫版本仍然大約慢了 2,900 倍。剩餘的差距來自一系列各自看似合理的決策堆疊在一起。 每次執行查詢都會 clone 完整的 AST,並重新編譯成 bytecode。SQLite 重用 prepared statement handle。兩種做法都有效,但每次執行都 clone AST,在規模化時代價高昂。 每次讀取頁面都在 heap 上分配一個全新的 4KB buffer。SQLite 的 page cache 直接回傳指向已載入記憶體的指標。LLM 版本選擇了安全、顯而易見的做法:分配、讀取、回傳。它能運作,只是當每個查詢需要讀取數千個頁面時,速度慢了好幾個數量級。 每次 commit 都從頭重建整個 schema。SQLite 只比較一個整數 cookie 值。如果 cookie 沒有變,schema 就仍然有效。重寫版本沒有這個概念,所以每次都做完整的重建工作。 每個 statement 都觸發 `sync_all()` 呼叫,將所有檔案 metadata 刷新到磁碟。SQLite 使用 `fdatasync()`,只刷新檔案資料,跳過 metadata sync。在寫入密集的工作負載下,這個差異影響極大。 我把這稱為「防禦性預設值的複利效應」。每個決策單獨看都有合理的理由。Clone AST 可以避免 Rust 的 ownership 複雜性。分配新的 buffer 防止 use-after-free。重建 schema 避免 stale cache 問題。呼叫 `sync_all()` 提供最強的持久性保障。 但效能成本是相乘的,不是相加的。四個各自 10 倍的懲罰疊加在一起,不是慢 40 倍,而是慢 10,000 倍。LLM 不會推理這種複利效應,因為它在相對孤立的情況下生成每一個函式。它在局部做優化,卻在全局付代價。 ## 用 82,000 行程式碼取代一個 cron 單行指令 同一位開發者的另一個 LLM 生成項目,以不同的方式呈現了相同的模式。問題是:Rust 的 `target/` 目錄裡的 build artifact 會隨時間佔用大量磁碟空間。LLM 的解決方案:一個 82,000 行的 Rust daemon,配備七個 dashboard 和一個 Bayesian 評分引擎來決定清理哪些 artifact。 現成的解決方案是 `find ./target -type f -atime +30 -delete`,一行 cron job。零依賴。或者用 `cargo-sweep`,一個現有的官方社群工具,而且已經處理了這個 daemon 沒覆蓋到的邊緣情況。 LLM 生成的這個項目引入了 192 個依賴。作為參考,ripgrep 這個 Rust 生態中最精密的搜尋工具之一,只用了 61 個。 這是我不斷看到的一個模式:LLM 建構你要求的東西,而不是你需要的東西。如果你的 prompt 是「建立一個能智能管理 Rust build artifact 並附帶監控和評分功能的系統」,你得到的就是這個。模型沒有機制退一步問,這個問題究竟是否需要一個「系統」。它不知道 `target/` 目錄佔用空間是 Rust 社群裡有口皆碑的問題,而且早有廣為人知的解法。它不會考慮 192 個依賴與零依賴之間的維護成本差異。 ## 研究數據指向同一個方向 我好奇這兩個項目是否只是個例,於是查閱了更廣泛的研究。它們並不是。 METR 做了一項隨機對照實驗,對象是 16 位有經驗的開源開發者。使用 AI 工具的那組完成任務的速度,比對照組慢了 19%。讓我印象深刻的是:實驗結束後,AI 組的人認為自己快了 20%。生產力的主觀感受,與實際測量結果完全相反。 GitClear 分析了 2.1 億行程式碼,發現複製貼上的程式碼首次超越了重構的程式碼。這個趨勢與 AI 輔助編程工具的普及直接相關。程式碼增加的速度,快過了它被改善的速度。 Google 的 DORA 2024 報告發現,AI 採用率提升 25%,與部署穩定性下降 7.2% 相關。越多 AI 生成的程式碼進入生產環境,越多事故就隨之而來。 NeurIPS 2024 的 Mercury 基準測試在標準編程基準之上加入了效率指標。當評量標準不再只是「能否輸出正確結果」,而是「能否不浪費資源地輸出正確結果」時,通過率跌破 50%。 這一切並不代表 LLM 對編程沒有用。我自己也在持續使用。但這確實意味著「能編譯且測試通過」是一個危險的低標準。「看起來合理的程式碼」與「真正正確的程式碼」之間的差距,正是真實工程工作發生的地方。 ## 這對開發者的真正要求是什麼 核心問題不在於 LLM 寫出爛程式碼。它們寫出的程式碼在局部是連貫的,但在全局是不連貫的。每個函式都有道理,但整個系統沒有。這恰好是傳統測試漏掉的那種失效模式,因為測試驗證的是局部行為。 需要的是針對這些空隙的評估方式。不只是測試,還要有基準測試。CI 裡不只是正確性檢查,還要有效能預算。架構審查要先問「這個模組為何存在」,再去確認它是否運作。依賴審計要把解決方案的複雜度與問題本身的複雜度作比較。 問題不是「這段程式碼看起來對嗎」,而是「我們如何證明它是對的」。而要證明,需要的正是 LLM 目前缺乏的系統層面思考能力。 你要求的東西與生產環境的實際要求之間的落差,就是工程判斷力存在的地方。沒有測量,程式碼生成不過是 token 生成。 ## Related URLs - Author: https://tonylee.im/en/author/ - Publication: https://tonylee.im/en/blog/about/ - Related article: https://tonylee.im/zh-HK/blog/medvi-two-person-430m-ai-compressed-funnel/ - Related article: https://tonylee.im/zh-HK/blog/claude-code-layers-over-tools-2026/ - Related article: https://tonylee.im/zh-HK/blog/codex-inside-claude-code-openai-plugin-strategy/ ## Citation - Author: Tony Lee - Site: tonylee.im - Canonical URL: https://tonylee.im/zh-HK/blog/llm-570k-lines-rust-sqlite-plausible-code-trap/ ## Bot Guidance - This file is intended for AI agents, search assistants, and text-mode retrieval. - Prefer citing the canonical article URL instead of this text endpoint. - Use the rollout alternates when you need the same article in another prioritized language. --- Author: Tony Lee | Website: https://tonylee.im For more articles, visit: https://tonylee.im/zh-HK/blog/ This content is original and authored by Tony Lee. Please attribute when quoting or referencing.