Source time Edition date
IndustrySimon Willison
parse_number() as a SQLite extension: C vs Rust
parse_number() 作为 SQLite 扩展:C 与 Rust
Simon Willison weighs a C versus Rust parse_number() SQLite extension, so developers must decide whether Rust's memory-safety guarantees justify the extra build friction for a small extension.
Judgment
Developers packaging SQLite extensions must pick a language: Rust buys memory safety and a ready strtod at the price of a 298–321 KB binary, while a hand-written C fast path is both the smallest at 14 KB and the fastest at 16–19 ns per row.
Basis
Simon Willison reports that four extensions implement the same parse_number() behavior, with tests covering type preservation, parsing rules and floating-point accuracy, and that all versions matched across 8 million fuzz checks. Artifact size: Rust was 321 KB with Rusqlite and 298 KB with sqlite-loadable-rs, versus 14 KB for C. Net cost per row over 2 million rows, lower is better: the first C version ran 67 ns on mixed data, 25 ns integers-only and 106 ns decimals-only because it leaned on strtod(); after he prompted for a custom decimal parser, new C hit 19 ns, 16 ns and 18 ns. Rusqlite ran 46/36/55 ns and sqlite-loadable 41/32/47 ns. The mechanism: C's strtod is roughly twice as slow as the Rust equivalent, which is why Rust was initially faster despite the larger artifact — the custom C fast path closed that gap.
- First C67 ns
- New C19 ns
- Rusqlite46 ns
- sqlite-loadable41 ns
Unclear The post never reports build friction: no compile times, cross-compilation setup, or how much extra C the fast path adds to maintain.
Next Check the linked simonw/research report for the new C fast-path source, then re-run the benchmark on a second toolchain to confirm the 16–19 ns figure holds.