Производительность дефлятора Java / Scala для сжатия набора битов

#java #scala #compression

#java #scala #сжатие

Вопрос:

У меня есть этот код Scala, который использует дефлятор / инфлятор Java.

   def compress(bytes: Array[Byte]): Array[Byte] = {
    val deflater = new java.util.zip.Deflater
    val baos = new ByteArrayOutputStream
    val dos = new DeflaterOutputStream(baos, deflater)
    dos.write(bytes)
    baos.close
    dos.finish
    dos.close
    baos.toByteArray
  }

  def decompress(bytes: Array[Byte]): String /*Array[Byte]*/ = {
    val deflater = new java.util.zip.Inflater()
    val baos = new ByteArrayOutputStream(512)
    val bytesIn = new ByteArrayInputStream(bytes)
    val in = new InflaterInputStream(bytesIn, deflater)
    var go = true
    while (go) {
      val b = in.read
      if (b == -1)
        go = false
      else
        baos.write(b)
    }
    baos.close
    in.close
    // String(byte[] bytes, Charset charset)
    new String(baos.toByteArray, "ASCII")
  }
 

Мне нужно сжать набор битов, в котором установлен только один бит (100-й бит из 13 x 8 = 104 бит).

 val bs = new util.BitSet()
bs.set(100)
val ba = bs.toByteArray
val z = gzip.compress(ba)
println(ba.size)
println(ba.mkString(":"))
println(z.size)
println(z.mkString(":"))
 

Я ожидаю некоторого значительного уменьшения размера, но в результате я сохраняю только один байт.

 13
0:0:0:0:0:0:0:0:0:0:0:0:16
12
120:-100:99:96:64:0:1:0:0:29:0:17
 

Это ожидаемые результаты для дефлятора Java? Есть ли лучший компрессор для этого случая?

Ответ №1:

Это ожидаемые результаты для дефлятора Java?

Это то, чего я ожидал. Алгоритм сжатия «deflate» предназначен для сжатия больших файлов. Для небольшого файла (13 байт) накладные расходы при кодировании, вероятно, уравновесят (или даже превысят) достигнутое сжатие.

Есть ли лучший компрессор для этого случая?

Я бы не ожидал, что какой-либо из алгоритмов сжатия, поддерживаемых стандартными библиотеками Java, будет работать намного лучше. Если вы хотите получить хорошую производительность на крошечных растровых изображениях, вам, вероятно, потребуется разработать пользовательский компрессор из первых принципов.

Например, разреженное растровое изображение может быть представлено как последовательность чисел (в данном случае byte значений), которые обозначают установленные биты, или как последовательность чисел, которые представляют последовательности последовательных единиц или нулей.

Ответ №2:

Я думаю, что проблема в том, что данные, закодированные в GZIP, содержат информацию заголовка, которая занимает байты. Обычно это не имеет значения, поскольку размер сжимаемых данных обычно намного больше.

ЕСЛИ у вас в основном нули (или любые прогоны с одинаковыми значениями) и несколько байтов чего-то еще, возможно, лучше использовать кодировку длины прогона.

ЕСЛИ у вас действительно установлен только 1 бит, вы можете придумать свою собственную кодировку, которая кодирует смещение этого единственного бита только в том случае, если набор битов имеет фиксированную длину.