Simon Willison用Claude生成四种parse_number() SQLite扩展:优化版C实现每行 16–19 纳秒
原作者称,优化后的C版在处理混合、整数和小数数据时均快于两个Rust版本,约为其两倍;普通C版因依赖strtod() 在十进制数据上反而更慢,补上快速解析路径后缩小差距。所有版本在 800 万次模糊检查中结果一致。
AI解读:作者让Claude(Opus 5.5)在C和Rust中实现同一parse_number() 行为:去掉逗号、美元和英镑符号及百分号,处理前导负号,无法解析时返回NULL。
体积上Rust扩展为 321 KB(Rusqlite)和 298 KB(sqlite-loadable-rs),C扩展为 14 KB;但初版Rust更快,作者称原因是Rust版的十进制解析比C的strtod() 快约一倍。
作者再让Claude自写C十进制解析函数,优化后约 200 万行测试中混合数据每行 19 纳秒、纯整数 16 纳秒、纯小数 18 纳秒,均低于两个Rust版本和初版C。
上述数字来自作者自行搭建的对比实验,并非独立评测;结果只对应这一解析函数和该测试数据,不能外推到其他扩展或负载。
Simon Willison发布一项对比研究:让Claude(Opus 5.5)用C和Rust分别实现同一个SQLite扩展函数parse_number(),把“-$1,234.56”“12.5%”这类字符串转成可求和、可排序的数值,并比较性能、代码复杂度与生成的 .so文件体积。
四种实现的体积与速度
按作者描述,该函数会去掉逗号、$、£ 和 %,处理前导负号,遇到无法解析的内容返回NULL。初版对比中,Rust扩展体积为 321 KB(使用Rusqlite)和 298 KB(使用sqlite-loadable-rs),C扩展为 14 KB。
体积小的C版没有更快。作者称Rust版的十进制解析相当于C的strtod() 且快约一倍,因此初版C在十进制数据上落后。随后作者要求Claude自写一个能追平或超过Rust的C十进制解析函数,得到“new C”版本。
- 体积:Rusqlite版 321 KB,sqlite-loadable-rs版 298 KB,C版 14 KB。
- 初版C处理混合数据每行 67 纳秒,纯整数 25 纳秒,纯小数 106 纳秒。
- new C处理混合数据每行 19 纳秒,纯整数 16 纳秒,纯小数 18 纳秒。
- Rusqlite版三项分别为 46、36、55 纳秒;sqlite-loadable-rs版为 41、32、47 纳秒。
测试范围与结果边界
作者称所有版本在 800 万次fuzz检查中结果一致,覆盖类型保持、解析规则和浮点精度。性能数据是约 200 万行上的每行净耗时,数值越低越好,由作者自行测量。
这些数字只对应parse_number() 这一个函数和作者设定的数据分布,属于单次对比实验,不能据此推断其他SQLite扩展或更大范围工作负载的表现。