Сжатие искомых объектов в Java обычно не очень хорошо ... не так хорошо.
Прежде всего вам нужно понять, что объект Java имеет много дополнительной информации, которая не нужна.Если у вас есть миллионы объектов, это накладные расходы миллионы раз.
В качестве примера приведем двойной связанный список.Каждый элемент имеет предыдущий и следующий указатель + вы сохраняете длинное значение (отметка времени) + байт для вида взаимодействия и два целых числа для идентификаторов пользователя.Так как мы используем сжатие указателей, мы 6Bytes * 2 + 8 + 4 * 2 = 28Bytes.Java добавляет 8 байт + 12 байт для заполнения.Это составляет 48 байт на элемент.
Теперь мы создаем 10 миллионов списков по 20 элементов в каждом (временные ряды событий кликов пользователей за последние три года (мы хотим найти шаблоны)).
Итак, мы имеем 200 миллионов * 48 байт элементов = 10 ГБ памяти (хорошо, не так много).
Хорошо, кроме того, что сборщик мусора убивает нас и накладные расходы в скалах JDK, мы заканчиваем с 10 ГБ памяти.
Теперь давайте используем нашу собственную память / хранилище объектов.Мы храним его как таблицу данных по столбцам, где каждый объект на самом деле представляет собой одну строку.Таким образом, у нас есть 200 миллионов строк в коллекции меток времени, предыдущего, следующего, userIdA и userIdB.
Предыдущий и следующий теперь указывают на идентификаторы строк и становятся 4 байтами (или 5 байтами, если мы превышаем 4 миллиарда записей (маловероятно)).
Итак, у нас 8 + 4 + 4 + 4 + 4 => 24 * 200 Mio = 4.8GB + проблем с GC нет.
Поскольку в столбце меток времени минимальные и максимальные значения времени хранятся, а все наши метки времени находятся в пределах трех лет, нам нужно всего 5 байтов для хранения каждой из меток времени.Так как указатель теперь хранится относительно (+ и -), и из-за того, что серии кликов своевременно тесно связаны, нам нужно в среднем только 2 байта для предыдущего и следующего, а для идентификаторов пользователей мы используем словарь, поскольку серии кликов рассчитаны примерно на 500 тыс. Пользователей.нам нужно всего три байта каждый.
Итак, теперь у нас есть 5 + 2 + 2 + 3 + 3 => 15 * 200Mio => 3 ГБ + словарь 4 * 500 К * 4 = 8 МБ = 3 ГБ + 8 МБ.Звучит иначе, чем 10ГБ, верно?
Но мы еще не закончили.Поскольку у нас теперь нет никаких объектов, кроме строк и данных, мы сохраняем каждую серию в виде строки таблицы и используем специальные столбцы, представляющие собой коллекции массивов, которые на самом деле хранят 5 значений и указатель на следующие пять значений + указатель на предыдущий.
Итак, у нас есть 10 миллионов списков с 20 записями в каждом (поскольку у нас есть накладные расходы), у нас есть в списке 20 * (5 + 3 + 3) + 4 * 6 (давайте добавим некоторые накладные расходы для частично заполненных элементов) => 20 * 11+ 5 * 6 => 250 * 10Mio => 2,5 ГБ + мы можем получить доступ к массивам быстрее, чем элементы ходьбы.
Но, эй, это еще не конец ... временные метки теперь относительно хранятся, требуя всего 3 байта на запись + 5 на первую запись.-> поэтому мы экономим намного больше 20 * 9 + 2 + 5 * 6 => 212 * 10Mio => 2,12 ГБ.А теперь мы сохраняем все это в памяти, используя gzip, и мы получаем 1 ГБ, так как мы можем хранить все это линейно, сначала сохраняя длину массива, все временные метки, все идентификаторы пользователей, что очень сильно делает наличие в битах шаблонов для сжатия,Поскольку мы используем словарь, мы просто сортируем его в соответствии с пригодностью каждого userId, чтобы быть частью серии.
И так как все является таблицей, вы можете десериализовать все практически со скоростью чтения, так что 1 ГБ на современном SSD стоит 2второй, чтобы загрузить.Попробуйте это с сериализацией / десериализацией, и вы услышите внутренний крик пользователя.
Поэтому, прежде чем когда-либо сжимать сериализованные данные, сохраните их в таблицах, проверьте каждый столбец / свойство, если оно может быть логически сжато.И, наконец, получайте от этого удовольствие.
И помните, что 1 ТБ (ECC) сегодня стоит 10 КБ.Ничего.И 1 ТБ SSD 340 евро.Так что не тратьте свое время на эту проблему, если вам действительно не нужно.