Оптимизированный C обогнал Rust в эксперименте с SQLite-функцией parse number()

В эксперименте Саймона Уиллисона оптимизированный C оказался быстрее двух вариантов Rust при разборе чисел в SQLite, а исходный C проигрывал на десятичных значениях.

Оптимизированный C обогнал Rust в эксперименте с SQLite-функцией parse_number(). Тематическая карточка Comrad404.

В эксперименте, опубликованном 8 ноября 2026 года, Саймон Уиллисон сравнил четыре SQLite-расширения с функцией parse_number(). После оптимизации C-вариант обрабатывал строку за 16–19 нс — быстрее двух вариантов на Rust, показавших 32–55 нс в замерах автора. Уиллисон описал эксперимент в своём блоге.

Функция предназначена для преобразования строк вроде -$1,234.56 и 12.5% в числа, пригодные для суммирования и сортировки в SQLite. Она удаляет запятые и символы валюты и процента, учитывает начальный минус и возвращает NULL, если строку нельзя разобрать.

Схема: Первоначальное расширение на C занимало 14 КБ; варианты Rust — 321 КБ с Rusqlite и 298 КБ с sqlite-loadable-rs.; Оптимизированный C оказался быстрее обоих Rust-вариантов во всех трёх категориях.
Основные элементы, разобранные в статье.

Сначала Rust опередил исходный C-вариант

Уиллисон попросил Claude Opus 5.5 помочь сравнить реализации на C и Rust. Первоначальное расширение на C занимало 14 КБ; варианты Rust — 321 КБ с Rusqlite и 298 КБ с sqlite-loadable-rs. При этом Rust сначала оказался быстрее. Уиллисон объяснил это тем, что использованный в Rust эквивалент функции C strtod(), по его словам, работал примерно вдвое быстрее.

Затем автор попросил Claude написать собственную функцию разбора десятичных чисел на C. В приведённых им замерах на двух миллионах строк стоимость обработки одной строки составила:

Реализация Смешанные данные Только целые Только десятичные
Исходный C 67 нс 25 нс 106 нс
Оптимизированный C 19 нс 16 нс 18 нс
Rust с Rusqlite 46 нс 36 нс 55 нс
Rust с sqlite-loadable-rs 41 нс 32 нс 47 нс

В таблице указана чистая стоимость обработки одной строки; меньшее значение означает более высокую скорость. Оптимизированный C оказался быстрее обоих Rust-вариантов во всех трёх категориях. Самое заметное изменение — на десятичных значениях: показатель C снизился со 106 до 18 нс.

Результат относится к конкретной реализации

В этом опыте исходный C-вариант уступал Rust на замерах производительности, но был значительно меньше по размеру. После замены подхода к разбору чисел C стал быстрее всех четырёх вариантов, а исходное преимущество Rust исчезло. Это сравнение одной функции и конкретных расширений, а не общий рейтинг языков: результат может измениться при другой задаче или реализации.

Уиллисон также сообщил, что все четыре версии совпали по результатам восьми миллионов fuzz-проверок. Это сообщение автора о его эксперименте, а не независимая проверка редакцией. Замеры и результаты проверок не следует автоматически переносить на другие задачи SQLite, платформы или реализации C и Rust.