【问题标题】:Efficiently write compressed values to stream有效地将压缩值写入流
【发布时间】:2015-07-15 15:23:18
【问题描述】:

目前,我正在尝试从现有的 C 代码中转换一些压缩算法。

编码和解码对我来说似乎并不难。它更多的是关于流(无论是文件还是套接字)的序列化。

输入为 12 位,压缩后的输出为 7 位。但是向流中写入内容总是需要写入整个 8 位。

因此,由于每个值总是剩余 1 位,这是否意味着我必须缓冲 7 个字节才能写入 8 个值?这将给出以下字节(而所有 1 都属于第一个值,所有 2 都属于第二个值,等等)

11111112
22222233
33333444
44445555
55566666
66777777
78888888

真正的编解码器或使用的语言都无关紧要(实际上:编解码器是 G.711,语言是 Golang)。所以go-Tag 可能不合适。

这有什么线索吗?

【问题讨论】:

  • 在 Go 中,你可以实现任何你想要的 io.Writer,并保持字节缓冲区的内部状态,并随心所欲地管理它。
  • 好的,谢谢。但重点不在于去。我在所有其他语言中都遇到过这个问题,其中字节是将信息写入流的最小单位。这个问题的重点是关于如何或多或少有效地编写“单个位”。
  • Go 与其他语言没有什么不同,这主要是一种架构限制。也许您可以更有效地压缩更大的块,例如您的方案下 8 组 12 字节将压缩为 7 字节。
  • 我不明白您是否想受标准流接口的约束,因为您始终可以创建自己的在位级别而不是字节级别上工作的接口。
  • 问题显然是当数据以 2 为基数时,您正在编码为 7 位字...您要么将浪费 12.5% 的空间,要么将拥有每次要读取值时进行按位运算。显而易见的解决方案是不使用与存储系统不协调的压缩算法。

标签: go compression codec


【解决方案1】:

使用二进制移位运算符一次将 7 位加载到位缓冲区中,并且只要位缓冲区有 8 位,就输出它。最后,如果还有剩余的位,则输出最后一个字节,其中包含缓冲区中的内容。

类似(不知道 Go,但这应该很接近):

bits = 0
bitbuf = 0
... some loop ...
    ...make your seven bits ...
    bitbuf |= sevenbits << bits
    bits += 7
    if bits >= 8 {
        output(bitbuf & 0xff)
        bitbuf >>= 8;
        bits -= 8;
    }
...
if bits > 0 {
    output(bitbuf)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-10
    • 2019-02-06
    • 2012-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多