Skip to content
AI News HubLIVE
Original source2 min read

parse_number() as a SQLite extension: C vs Rust

Summary

Simon Willison used Claude to explore building a SQLite parse_number() extension in C versus Rust: Rust binaries were far larger (298–321 KB vs 14 KB) and initially faster, but a re-optimized C version reached 16–19 ns per row, roughly twice as fast as the Rust versions.

parse_number() as a SQLite extension: C vs Rust
Report an error

The correction channel is not available yet. You can copy the article reference below for later.

Correction instructions
Read article

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

Simon Willison’s Weblog

Newsletter

8th November 2026

Research

parse_number() as a SQLite extension: C vs Rust — Four SQLite extensions implement the same parse_number() behavior in C and Rust, with tests covering type preservation, parsing rules, and floating-point accuracy. The optimized C implementation was fastest at 16–19 ns per row, about twice as fast as the Rust versions and far faster than SQL replace(). Plain C was slower on decimals because it relied on strtod(), while a compact fast path closed that gap; all versions matched across 8 million fuzz checks.

I was out walking the dog when I got curious about how easy/difficult it would be to write a SQLite C extension that adds a parse_number() function for turning strings like -$1,234.56 or '12.5%' into numeric values that could be summed and sorted.

I fired up regular Claude chat (Opus 5.5) and prompted:

I'm thinking about a SQLite custom function 'parse_number(value)' that strips ',', '$', '£' and '%', handles a leading '-', and returns 'NULL' for anything it can’t parse

Explore the difference between building this as a SQLite extension in C v.s. in Rust - I want to compare performance and code complexity and size of the resulting.so(or whatever) file

This gave me a solid starting point - the Rust extension was 321 KB (using Rusqlite) and 298 KB (using sqlite-loadable-rs), while the C extension was 14 KB. But the Rust extension was faster!

Turns out that's because the Rust equivalent of C's strtod is "twice as fast". So I prompted:

Try writing your own C function for parsing text into a decimal number that catches up to or beats the Rust implementation

And it did:

Net cost per row over 2 million rows, lower is better:

first C new C rusqlite sqlite-loadable

Mixed data 67 ns 19 ns 46 ns 41 ns

Integers only 25 ns 16 ns 36 ns 32 ns

Decimals only 106 ns 18 ns 55 ns 47 ns

Finally, I had it rewrite the prototype as a research report to match the others in simonw/research by prompting this:

Clone simonw/research from GitHub and turn your above investigation into a research report as seen in that repository - you can give me a zip file to download that contains your new folder

Here's the resulting report.

Recent articles

Qwen 3.8 27B on my laptop can interpret model weights, too - 3rd November 2026

The U.S. Census Bureau and “Super Intelligence” - 2nd November 2026

The October inflection point for vibe game development - 28th October 2026

Battle Drones - a vibe coded RTS with audio-based multiplayer - 20th October 2026

This is a beat by Simon Willison, posted on 8th November 2026.

c 55

research 12

sqlite 490

rust 116

claude 324

Monthly briefing

Sponsor me for $10/month and get a curated email digest of the month's most important LLM developments.

Pay me to send you less!

Sponsor & subscribe

Disclosures

Colophon

©

2002

2003

2004

2005

2006

2007

2008

2009

2010

2011

2012

2013

2014

2015

2016

2017

2018

2019

2020

2021

2022

2023

2024

2025

2026

Key points and analysis

Article intelligence

EngineersAdvanced

Key points

  • Rust extensions were 298–321 KB versus 14 KB for the C extension
  • Plain C was slow on decimals due to strtod, but an optimized fast path closed the gap
  • Optimized C hit 16–19 ns per row, about twice as fast as both Rust implementations
  • All versions matched across 8 million fuzz checks

Highlights and analysis are generated automatically and may contain errors. Check the original source.