学习精选 · AI 工具
AI 学习经验

用 Claude 写 SQLite 扩展:同一个 parse_number(),C 和 Rust 差在哪

Simon Willison2026-11-09约 3 分钟读完AI 整理查看原文

Simon Willison 遛狗时想到给 SQLite 加一个 parse_number() 函数,把 '-$1,234.56'、'12.5%' 这类字符串转成可求和排序的数值。他用 Claude 对话依次探索 C 和 Rust 两种实现,对比性能、代码量和产物体积,最后让 AI 把整个过程整理成研究报告。

今天就能做

  • 给 SQLite 写自定义函数时,C 扩展体积小得多(14 KB vs 约 300 KB),但性能要自己写解析逻辑才能发挥出来
  • 遇到 AI 给出的性能意外结果,可以直接让它针对瓶颈重写,一轮对话就能把 106 ns 优化到 18 ns
  • 用 fuzz 测试对比多个实现的输出一致性,是验证 AI 生成代码正确性的低成本手段

起点:一次对话拿到两个原型

  • 目标函数 parse_number(value):去掉逗号、$、£、%,处理负号,解析失败返回 NULL
  • Claude(Opus 5.5)一次就给出可用的 Rust 和 C 版本
  • 产物体积差距明显:Rust 用 Rusqlite 是 321 KB,sqlite-loadable-rs 是 298 KB,C 只有 14 KB

意外结果:Rust 反而更快

  • 初步基准测试中 Rust 版本跑赢了 C 版本
  • 原因是 Rust 里对应 C strtod 的解析实现快了约一倍
  • 于是追加提示词:让 Claude 自己写一个能追平或超过 Rust 的 C 解析函数

优化后的性能数据

  • 在 200 万行上测每行净耗时:混合数据从 67 ns 降到 19 ns,Rusqlite 46 ns,sqlite-loadable 41 ns
  • 纯整数场景:新 C 版 16 ns,Rust 两版分别为 36 ns 和 32 ns
  • 纯小数场景差距最大:初版 C 106 ns,优化后 18 ns,Rust 为 55 ns 和 47 ns
  • 优化 C 版整体比 Rust 快约一倍,远快于用 SQL replace() 拼接的做法

正确性验证与产出

  • 四个实现(两个 C、两个 Rust)在 800 万次 fuzz 检查中结果完全一致
  • 关键优化是给小数解析加了一条紧凑的快速路径,绕开 strtod 的开销
  • 最后让 Claude 克隆 simonw/research 仓库,把调查过程改写成一份研究报告打包下载

值得借鉴的工作方式

  • 整个项目由三段递进提示词完成:先探索对比,再针对性优化,最后整理成文
  • 让 AI 对比自己写的两个版本,比单看一个实现更容易发现性能盲点
  • 把探索过程沉淀为可复用的研究报告,而不是散落在聊天记录里

原文:Research: parse_number() as a SQLite extension: C vs Rust

来源:Simon Willison

查看原文

本文由 AI 阅读原文后整理,未经人工逐字核对,内容以原文为准。

登录后可以点赞、查看和发表评论