Будущее кодирования: compressed execution и AnyBlox
В предыдущих четырёх уроках мы разобрали cutting-edge кодировки: BtrBlocks (каскады), FastLanes (SIMD-layout), ALP (float→integer), FSST (символьные таблицы). Каждая из них улучшает сжатие — но все предполагают, что данные нужно декомпрессировать перед обработкой.
Этот урок — о следующем шаге: что если вообще не декомпрессировать?
Compressed Execution: работа на сжатых данных
Традиционный pipeline аналитического запроса: читаем сжатые данные с диска → декомпрессируем в память → обрабатываем (filter, aggregate, join) → возвращаем результат. Декомпрессия — обязательный шаг, и он стоит CPU-циклов.
Compressed execution пропускает декомпрессию: операции выполняются прямо на сжатых данных. Не все операции и не на всех кодировках — но для определённых комбинаций это работает.
Обрабатываем 100% данных в full size
Каждый шаг pipeline работает с полноразмерными данными. Если колонка сжата 5x — pipeline обрабатывает 5x больше байтов, чем необходимо. Memory-bandwidth bound на modern hardware.Декомпрессируем только matches (~1%)
Filter работает на сжатых данных → отсеивает 99% строк → декомпрессируем только 1%. Экономия: 99% декомпрессии пропущено.DuckDB: три типа compressed vectors
DuckDB реализует compressed execution для трёх типов кодировок:
Compressed execution не универсален: JOIN по Dictionary vectors требует совместимых словарей, LIKE на FSST — частичного декодирования, а математические операции (SUM, AVG) на Constant vectors — специальной логики. DuckDB реализует compressed paths для самых частых операций и fallback на decompress для остальных.
Partial Decompression: декодирование одного значения
FastLanes (Урок 04) открывает другую возможность: partial decompression. Благодаря UTL layout, можно декодировать одно значение из блока в 1024, не трогая остальные 1023.
Decode 1024 значений ради одного. O(block_size)
Стоимость: O(block_size). Для 1024 × 4-byte values = decode 4 KB, даже если нужно 4 байта.Decode 1 значение. O(1)
Стоимость: O(1). Один lane lookup + один bit-unpack. Полезно для: point queries (WHERE id = 500), index lookups, late materialization (декодируем только колонки, которые прошли filter).Partial decompression полезна для late materialization: сначала filter на сжатых данных → получаем позиции match’ей → декодируем только нужные значения из нужных колонок. Комбинация compressed execution (filter без decode) + partial decompression (decode только matches) минимизирует объём декомпрессии.
AnyBlox: WebAssembly-декодеры внутри данных
Все форматы (Parquet, ORC, Arrow) имеют одну проблему: формат задаёт набор кодировок. Parquet поддерживает PLAIN, RLE_DICTIONARY, DELTA_BINARY_PACKED и ещё 6 типов — и всё. Новая кодировка (например, ALP) требует изменения спецификации, обновления всех reader-библиотек (pyarrow, spark, polars, duckdb, …), и ожидания adoption. Процесс занимает годы.
AnyBlox предлагает радикальное решение: вместо фиксированного набора кодировок — положить декодер рядом с данными.
Проблема: writer знает ALP, reader не знает ALP → data unreadable
Традиционная проблема: writer хочет использовать новую кодировку (ALP, FSST, FastLanes cascade). Но reader не поддерживает её — data loss. Format version lock-in.Writer: любая кодировка. Reader: всегда прочитает.
Результат: формат данных отвязан от набора кодировок. Writer может использовать ЛЮБУЮ кодировку — experimental, proprietary, bleeding-edge — и reader всегда прочитает, потому что декодер поставляется вместе с данными.Почему WebAssembly?
AnyBlox — исследовательский проект, не production-ready формат. Открытые вопросы: стандартизация metadata (как reader находит Wasm модуль в файле?), доверие к декодерам (Wasm sandbox не предотвращает denial of service — бесконечный цикл), и производительность Wasm для SIMD-intensive декодеров (Wasm SIMD proposal всё ещё созревает).
Направления исследований
Encoding research — одна из самых активных областей в data systems. Несколько направлений:
Таймлайн: от классических кодировок к compressed execution
Итог модуля
Модули 08 и 09 прошли полный путь — от информационной теории и классических кодировок через кросс-форматный анализ до cutting-edge исследований:
- Encoding ≠ compression: кодирование трансформирует данные (Dictionary, FOR, Delta, FSST, ALP), compression сжимает байты (LZ4, Zstd). Максимальный эффект — кодирование перед компрессией (BtrBlocks cascade).
- SIMD — бесплатно: FastLanes UTL layout даёт автовекторизацию без платформенных intrinsics. >100 млрд int/sec на scalar коде.
- Float — сжимаем: ALP превращает «несжимаемые» float64 в integers. 4–8x на финансах/сенсорах.
- Строки — random access: FSST даёт ~3x без потери random access. Late decompression: предикаты на сжатых строках.
- Декомпрессия — не обязательна: compressed execution (DuckDB vectors), partial decompression (FastLanes), late decompression (FSST) — три способа обойти полную декомпрессию.
- Форматы эволюционируют: от фиксированных enum кодировок (Parquet/ORC) к expression encoding (FastLanes FF) и WebAssembly-декодерам (AnyBlox).
Все ключевые техники (FastLanes, ALP, FSST) интегрированы в DuckDB — открытый аналитический движок, ставший playground для encoding research из CWI Amsterdam.