2015-12-21 2 views
0

Моя цель - хранить сотни отдельных файлов максимально эффективно и читать с использованием Java 1.6. Файлы состоят в среднем из 125 000 номеров. В некоторых файлах содержится несколько сотен номеров, что составляет более 7 000 000 экземпляров. В большинстве случаев номера диапазона от 0 до 255, 1 байт могут быть сохранены. В некоторых случаях номера диапазона 0-1024, 2 байта.Сжатие чисел более 256 (1 байт) с BZip2/GZip

Для сохранения данных я использую BZip2 implementations of Apache. Но BZip2 может хранить только номера размером не более 1 байт. Вот почему я написал класс, который делит последовательность целых чисел в битах и ​​объединяет 8 бит в 1 байт. Эти байты затем записываются в CBZip2InputStream (BZip2 OutputStream). Комбинация обоих алгоритмов работала достаточно хорошо. К сожалению, мой алгоритм очень медленный в чтении. В приведенной ниже таблице показано время в миллисекундах, которое требуется для чтения файлов с 125 000 номеров.

| Gzip | BZip2 | UTF-8 | мой алгоритм |

| 47 | 28 | 35 | 1008 |

| 37 | 12 | 13 | 856 |

| 25 | 11 | 10 | 845 |

| 25 | 12 | 5 | 862 |

Мой алгоритм примерно в 56 раз медленнее, чем BZip2.

Есть ли другой способ эффективно сжимать числа, состоящие из более чем 8 бит. В частности, скорость чтения должна быть наиболее важной. Скорость чтения должна быть в 2-4 раза выше при аналогичном высоком сжатии, как BZip2. Если нет другого способа, вы отправите мой исходный код и объясните, если это необходимо для его оптимизации.

+3

Непонятно, почему вы думаете, что необходим другой алгоритм сжатия. Каждое из ваших номеров разбивается на байты, которые затем могут быть сжаты любым алгоритмом сжатия, включая BZip2. Если многие байты являются нулями, то алгоритмы сжатия будут учитывать это и соответственно сжимать. Вы вряд ли превзошли популярный алгоритм сжатия. –

+0

Каковы коэффициенты сжатия. Такие вещи, как bzip/gzip, могут поставляться с приличным сжатием. – mksteve

+0

С данными Bzip2 снижается до 40%. @mksteve – MaggiCraft

ответ

0

Похоже, ваша схема кодирования очень неэффективна. Попробуйте использовать библиотеку, которая выполняет преобразование для вас. См., Например, протоколы-буферы, но любой другой будет прекрасно.

В противном случае я ожидаю, что вы используете битовые операции, чтобы убедиться, что код работает как можно быстрее. Нравится:

byte[2] out; 
int x; 
out[0] = x & 0xff; 
out[1] = x >> 8; 

x = out[0] + (out[1] << 8); 

Медленность может быть вызвана тем, что вы очень часто запрашиваете очень небольшое количество данных. Попробуйте использовать несколько большой буфер перед чтением.

+0

До сих пор я не нашел никакой библиотеки, а затем конвертировал целое число в битах и ​​байтах и ​​битах во всем назад. Я попытаюсь улучшить алгоритм с помощью операций. Я также буду экспериментировать с размером буфера. Я не понял, что такое протокольные буферы. Я не знаю, как они могут помочь мне хранить данные. @Sorin – MaggiCraft

+0

протокольные буферы - это совокупность общих процедур обработки данных, которые включают в себя сериализацию и десериализацию среди многих других. Они оптимизированы для скорости. В вашем случае вы можете определить bufferbuffer с одним повторным полем int (это ваш массив) и позволить ему конвертировать код протокола для преобразования в и из потока (или массива байтов). Закодированные данные занимают немного больше места, но я думаю, что он будет сжиматься так же хорошо. – Sorin

Смежные вопросы