Задать вопрос
@firstmixon

Есть ли способ сжать данные?

День добрый!
Есть структура данных(~ 10 полей целочисленных), часть из которых реально занимает int8, а часть только int, так как данных чуть больше чем дофига(1 000 000, записей), данные отъедают много памяти, есть ли вменяемые способы оптимизации, или только вариант упаковки пары int в одно поле int8?
  • Вопрос задан
  • 119 просмотров
Подписаться 2 Простой 8 комментариев
Пригласить эксперта
Ответы на вопрос 1
@rPman
1. хранение без сжатия, самое простое для реализации - плоские массивы на каждый элемент, типа например структура (int a, int8 b) то нужно создать два массива int[] a и int8[] b (это некрасиво ломает оптимизации кеша работы с ram если данные по каждому объекту нужны целиком сразу, ну и конечно, никто не заставляет так делать со всеми данными, но у вас python вам и так грустно)
Еще вопрос к python, на сколько я помню для работы с массивами данных там numpy подходит (имеется в виду эффективные операции с данными а не сам доступ)

Сразу скажу, с упаковкой данных на python работать будет отвратительно неудобно и медленно! Лучше сразу переходить на c/c++ и подключать его как модуль расширения python.

что бы пропустить что написано ниже - вот пример библиотеки
https://github.com/ghilesmeddour/gorilla-time-seri...

2. если этого недостаточно, самый простой механизм сжатия целочисленных данных в массиве, особенно если данные - показания во времени, не сильно меняющиеся (т.е. соседние данные отличаются на значение, занимающее меньше int, то хранить в массиве не сами данные, а разницу от предыдущего (или от базы для блока, базы хранить в отдельном массиве), например последовательсность 12322 12320 12325 12319 можно хранить как:
первое число 12322 и последовательность -2,5,-6.

в этом случае случайный доступ не получится, для получения следующего числа нужно последовательно обработать весь массив, но можно кешировать значение базы для каждого N.
ну или такой:
база 12322 в виде одного числа, и массив 0,-2,3,-3... числа в этом массиве могут влезать не просто в int а в int8

Если зафиксировать интервал между смены базы (например каждый 1024 числа), то случайный доступ не будет проблемой.

Для значений, разница с базой которых выходит за возможности ее хранения (например для int8 это вне -128..127) можно выбрать какое-нибудь значение, например -128 как сигнал что разница слишком большая, и само число хранить в отдельном map(индекс,значение)... если таких выходов за границу будет относительно мало, подход будет эффективным

В обоих примерах эффективная запись новых значений будет затруднена (но не невозможна, просто медленнее)

p.s. ключевые слова для гугла - delta encoding, frame-of-reference, time series compression, escape value/exception coding, Apache Parquet, ClickHouse, Gorilla Time Series (честно я сначала описал технику а потом попросил ИИ найти где это используется, ее не проверял но техника очень простая и популярная, да та же квантизация llm рядом стоит)

upd. Дальнейшее расширение подхода - динамическое изменение количества байт или даже бит на хранение разницы с базой, например мы можем хранить в массиве 1байтовые, 2-байтовые, 3-байтовые разницы и 4-байтовое само число, но вынуждены где то хранить по 2 бита на указание, какое именно сейчас используется, 00 - для int8, 01 - для int16, 10 - для int24 (не советую хранить эти биты в самих смещениях, хотя для 2-байтовых это может быть оправдано, но 4-байтового может тогда не хватить для хранения самого значения)... например отдельный массив для битовых пар, и несколько динамических массивов соответственно для int8, int 16, int24 и int32, но для понимания, по какому адресу какое значение хранится, придется анализировать массив битовых пар, например в нем указано хранение 0,0,1,1,2,0,3 что говорит что 1,2 и 6 числа будут храниться в массиве int8, а 3и 4-ое в массиве int16,.. т.е. такой подход будет эффективно работать для поседовательного чтения но плохо для случайного.
p.s. variable byte encoding, dynamic encoding, bit-packing, Parquet, ORC, protobuf varints

как же классно стало с современным ИИ, это гугл на стероидах, он и утверждения проверит, и погуглит алгоритмы и даже предложит куски кода по желанию (само собой придумает половину несуществующих, всегда об этом нужно помнить и перепроверять!)
https://en.wikipedia.org/wiki/Delta_encoding
https://www.vldb.org/pvldb/vol8/p1816-teller.pdf
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы