惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

aimingoo的专栏
aimingoo的专栏
O
OpenAI News
B
Blog
阮一峰的网络日志
阮一峰的网络日志
博客园_首页
罗磊的独立博客
Hugging Face - Blog
Hugging Face - Blog
Martin Fowler
Martin Fowler
博客园 - 司徒正美
美团技术团队
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Vercel News
Vercel News
Recent Announcements
Recent Announcements
MyScale Blog
MyScale Blog
D
Docker
S
SegmentFault 最新的问题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
H
Hackread – Cybersecurity News, Data Breaches, AI and More
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
量子位
博客园 - 【当耐特】
云风的 BLOG
云风的 BLOG
Blog — PlanetScale
Blog — PlanetScale
V
V2EX
博客园 - Franky
宝玉的分享
宝玉的分享
C
CERT Recently Published Vulnerability Notes
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Simon Willison's Weblog
Simon Willison's Weblog
Recorded Future
Recorded Future
T
The Blog of Author Tim Ferriss
T
Tor Project blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
I
Intezer
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
雷峰网
雷峰网
T
Threatpost
Cisco Talos Blog
Cisco Talos Blog
L
LINUX DO - 热门话题
SecWiki News
SecWiki News
I
InfoQ
T
The Exploit Database - CXSecurity.com
Hacker News - Newest:
Hacker News - Newest: "LLM"
P
Privacy & Cybersecurity Law Blog
T
Troy Hunt's Blog
Latest news
Latest news
MongoDB | Blog
MongoDB | Blog
T
Tenable Blog
博客园 - 叶小钗
Attack and Defense Labs
Attack and Defense Labs

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Мой универсальный код
Максим · 2026-05-19 · via Все публикации подряд на Хабре

Мой универсальный код

Простой

4 мин

10K

Зачем я переплачиваю 31 бит на число 1?

Зачем на число 1 я в типах u8, u16, u32 и так далее переплачиваю 7, 15 и 31 бит? Это же бред.

Однозначность декодирования? Быстрая адресация? Сейчас распишу до чего я допёр.

Проблема

Если биты лежат в потоке, то не совсем понятно что они значат без предварительной договорённости. Например:

1110101011

Что это? Одно число? Два? Бог его знает. Без какого-то знания начального подойти к данным не выйдет (я работаю над этим :D).

Можно заранее договориться читать кусками по 8, 16 или 32 бит — тогда ничего не надо придумывать, тупо читай. Но тогда платишь налог на ненужные биты и возможны переполнения. В целом для прикладных задач этого кому-то хватает.

Но я люблю хардкор.

Кодируем длину рядом с данными

Я подумал: а почему бы не записывать длину рядом с данными? Тогда декодер знает сколько бит читать.

Самый тупой способ — унарный код: ставим нолики перед числом, сколько ноликов — столько бит в числе:

0 1         ← один ноль: число из 1 бита → "1" → число 1
00 10       ← два ноля: число из 2 бит → "10" → число 2
000 101     ← три ноля: число из 3 бит → "101" → число 5
0000 1100   ← четыре ноля: число из 4 бит → "1100" → число 12

Работает! Но оверхед — ровно n бит на число длины n. Число из 20 бит потребует 20 нолей перед ним. Мерзкая линейность!

Рекурсия спасает

А что если длину тоже кодировать чем-то компактным? Длина числа 1100 — это 4. Четвёрку можно записать в 2 бита: 100. А длину четвёрки — в 1 бит…

Если так рекурсивно продолжить, то упрёмся в стартовые два бита — потому что только два бита могут закодировать длину больше своей (2 бита кодируют числа до 3, а 3 > 2).

Пример: кодируем число 12 (1100, длина 4):

Цепочка длин: 4 → 2 (длина четвёрки) → стоп (2 влезает в 2 бита)

Записываем:
11        ← база: число 3 (говорит "следующий блок из 3 бит")
100       ← число 4 (говорит "следующий блок из 4 бит")  
1100      ← само число 12
0         ← терминатор "конец"

Итого: 10 100 1100 0 = 10 бит на число 12
Фикса u8 потратила бы 8, но на больших числах рекурсия выигрывает

Поздравляю, мы с вами придумали омега-кодирование Элиаса (1975)!

Оно довольно неплохое, оверхед на число длины n бит:

\log n + \log \log n + \log \log \log n + \ldots

А если кодировать не длину, а число единиц?

Но я подумал: а почему бы не кодировать не длину, а число единиц (popcount)?

В худшем случае когда все биты — единицы, popcount = длина. Деградация до омеги, которая и так хорошая.

Но в лучшем случае — ммм… Допустим, число 10000000000 (1024). Длина — 11 бит. А единица в нём — всего одна!

Омега кодирует длину 11 → рекурсия на 11, потом на 3, потом база. Много уровней. Мой код кодирует popcount 1 → это сразу влезает в базу из 2 бит. Один уровень!

Вот как это работает пошагово:

Кодируем число 1024 = 10000000000 (11 бит, popcount = 1)

Шаг 1: popcount = 1, влезает в 2 бита → база = 01
Шаг 2: записываем число задом наперёд: 00000000001
        (реверс нужен чтобы декодер мог считать единицы —
         последняя единица всегда MSB, он до неё дочитает и остановится)
Шаг 3: терминатор = 1

Итого: 01 00000000001 1 = 14 бит
u16 потратил бы 16 бит. Мы сэкономили.

А теперь большое число: 10000000000000000000001000000000000001 (попробуйте в u64!):

Длина: 35 бит. Единиц: всего 3.

Шаг 1: popcount = 3 → база = 11 (два бита)
Шаг 2: число задом наперёд (35 бит)
Шаг 3: терминатор = 1

Итого: 11 + 35 + 1 = 38 бит
u64 потратил бы 64 бита. Экономия 26 бит!

Почему терминатор вообще работает? Мы перед данными написали число единиц, которое надо прочитать декодеру, значит первая единица которая нарушает это число - терминатор.

Фишка: чем ближе число к степени двойки (мало единиц) — тем меньше метаданных. Я могу конечным числом бит описать декодеру сколь угодно длинное число.

А в худшем случае (все биты единицы)? Popcount = длина, и мой код работает ровно как омега. Никогда не хуже!

А что с VByte?

Кстати, помните унарную длину из начала? 000 101 — три нуля говорят “читай 3 бита”. Это и есть гамма-кодирование Элиаса: длина унарно + данные. Просто и рабочее, но линейный оверхед.

VByte (LEB128/Varint) — это по сути то же самое гамма-кодирование, только каждый бит гаммы кодирует 7 битов длины а не 1. В целом для большинства задач этого хватает.

Но всё равно рост оверхеда линейный: 1 бит на каждые 7 бит данных = 14.3% налог навсегда. И число 1 всё равно стоит минимум 8 бит.

У меня число 1 стоит 4 бита. Число 2 — тоже 4 бита.

Единственная проблема

Единственная проблема моего подхода, как и любого рекурсивного универсального кода — нельзя просто прыгнуть по индексу в потоке и прочитать.

НО. Никто не мешает хранить, например, индекс каждого 16-го узла в той же кодировке. И индексы каждого 16-го индекса. И так далее. В таком случае навигация становится O(\log n), а индекс весит крохи по сравнению с самими данными.

Вот такие фокусы!

Бенчмарки

Я не просто теоретизирую — всё реализовано на Rust и протестировано на миллионе чисел.

Что сравниваем

Результат

Оверхед метаданных vs Elias Omega

на 36% меньше

Размер vs VByte на плотных дельтах (с индексом)

в 1.55 раза компактнее

Сырые данные (дельты ~2) vs VByte

в 2 раза компактнее

Число 1 у меня — 4 бита. У VByte — 8 бит. Число 1024 у меня — 14 бит. У VByte — 16 бит. На маленьких числах (а дельты в поисковых индексах почти всегда маленькие) разница огромная.

Round-trip тестирование пройдено для всех значений вплоть до u64::MAX.

Реализация

Рабочий MVP на Rust лежит на GitHub, лицензия MIT. Код, бенчмарки, PDF с доказательством — всё там:

GitHub — Permyakov Code


P.S. Хочу опубликовать теорию в научном журнале или на arXiv — PDF с доказательством строгого доминирования уже готов. Если у вас есть возможность помочь с эндорсментом на arXiv (cs.IT / cs.DS) или вы знаете подходящий журнал — буду очень благодарен, пишите в личку!