How is Ultrassembler so fast?
Ultrassembler — библиотека RISC-V-ассемблера, встроенная в проект Chata.
В отличие от as и llvm-mc, она вызывается прямо из C++, без system() и временных файлов, что критично для встроенных систем.
Скорость
Тест на 16 тыс. инструкций:
- Ultrassembler ≈ 10× быстрее
as, 20× быстрееllvm-mc. - 1 RISC-V инструкция ≈ 1000 x86-инструкций (у конкурентов 10–20 тыс.).
Код на чистом C++; можно добавить ассемблерные вставки.
Ключевые оптимизации
Исключения
GCC-реализация «zero-overhead»: штрафа нет, пока исключений нет.
Ошибки встречаются редко и видны человеку, поэтому даже 1 с на обработку незаметна.
std::expected дал −10 %, так как нормальный путь стал дороже.
Быстрые структуры
2000+ RISC-V-инструкций требуют мгновенного поиска.
Вместо std::unordered_map используется perfect-hash таблица от gperf, генерирующая O(1) без коллизий.
Размер таблицы компактен, кэш-эффективен.
Парсинг
- Регистры идентифицируются по первым 2–3 символам через
switch. - Нет
std::string, толькоstd::string_viewи статические буферы. - Лексемы разбираются за один проход без регулярных выражений.
Кодогенерация
- Шаблоны на этапе компиляции формируют битовые маски инструкций.
- Варианты одной инструкции разворачиваются в
constexpr-таблицы, что убирает ветвления в рантайме.
Память
- Все выделения через стековые
std::array/std::string_view. - Нет
new/malloc, следовательно, нет аллокационных штрафов и кэш-промахов.
Платформенные трюки
[[likely]]/[[unlikely]]для подсказок ветвления.__builtin_expectтам, где компилятор не догадывается.- LTO + PGO дают ещё 5–7 %.
Итог
Ultrassembler показывает, что «низкоуровневый» C++ без искусственных ограничений может обгонять даже оптимизированные GNU-утилиты.
Комментарии (34)
- В обсуждении разобрали миф о «системном вызове при каждом росте контейнера» — реальные аллокаторы переиспользуют память и делают syscall лишь при нехватке.
- Участники напомнили, что исключения в C++ не «zero-overhead»; есть компромисс между временем и памятью, и g++ выбирает экономию места.
- Автор статьи подтвердил: пробовал хеширование, но дерево разбора оказалось быстрее; flex/bison тут не при чём, скорее gperf.
- Некоторые посоветовали LLVM C++ API, memory-mapped I/O и std::pmr для ускорения и упрощения кода.
- Большинство сходится: современные ассемблеры и так быстрые, задача скорее академическая, но как «посмотреть, насколько можно ускорить» — интересна.
A spellchecker used to be a major feat of software engineering (2008) 💬 Длинная дискуссия
1984: словарь в 256 КБ
Представьте: вам поручили написать спеллчекер для MS-DOS-текстового редактора. У части пользователей всего 256 КБ ОЗУ — и туда должны поместиться редактор, сам документ, ОС и ещё словарь. Сегодня /usr/share/dict/words весит 2,5 МБ и содержит 235 000 слов; тогда это был нереальный объём.
Сжатие трие, вырезание редких слов, кастомная БД на гибком диске 360 КБ — всё это требовало месяцев инженерной работы и гениальных структур данных.
Сейчас
Загрузить словарь в хеш-таблицу — 3–5 строк на Perl или Python; поиск слова — встроенная операция. Всё.
Комментарии (176)
- Пользователи жалуются, что встроенный спелл-чекер iPhone (и Android) часто хуже человеческого глаза и LLM: «No Guesses Found» при очевидных ошибках.
- Причины: жёсткие ограничения по скорости и памяти, отсутствие контекста, излишняя буквальность алгоритмов.
- Многие отказались от встроенных средств и ищут слова в Google или используют LLM.
- Участники вспоминают, как в 80-е спелл-чекер был прорывом, но требовал переключения дискет и выдавал лишь список ошибок без подсказок.
- Сегодня задача «проверить орфографию» тривиальна, а вот «предложить правильное» по-прежнему требует сложной инженерии.