算术编码的隐形坑:你的压缩为啥总丢比特?

算术编码的隐形坑:你的压缩为啥总丢比特?

五月 04, 2026 compression arithmetic-coding entropy-coding algorithms performance-optimization cloud-computing developer-experience

算术编码的隐形坑:你的压缩为什么总在浪费比特?

搞过算术编码的同学,肯定觉得自己挺牛。算法优雅,把比特序列映射到概率区间,一气呵成。可问题是,网上那些基础实现,基本都在悄悄拉胯

不是说速度慢(虽然CPU周期也重要)。重点是压缩比——你用entropy coding不就为这个吗?

课本代码的猫腻

你肯定见过这种入门代码:

let mut left: u32 = 0;
let mut right: u32 = u32::MAX;

fn encode_bit(bit: bool, probability: f32) {
    let mid = left + ((right - left) as f32 * probability) as u32;
    if !bit {
        right = mid;
    } else {
        left = mid + 1;
    }
    
    while left >> 24 == right >> 24 {
        output_byte((left >> 24) as u8);
        left <<= 8;
        right = (right << 8) | 0xff;
    }
}

看着顺眼吧?维护[left, right]区间,每来个比特就按概率缩区间。顶字节确定了,就吐出去,腾空间。

问题是,这代码有隐藏不对称,和数学理想版不符

字节边界捣乱

怪事来了。理想算术编码里,同等长度的区间一视同仁。但32位整数实现里,不行。

举例:

  1. left从0起步,区间最小也就2^24比特
  2. left从2^31-1起步,能缩到2比特那么小

为啥?看输出条件:left >> 24 == right >> 24。这玩意儿看位置,不光看长度。

区间卡在字节边上,比如[2^31-1, 2^31],就容易变窄。概率0.95的比特,硬被量化成50/50。因为区间太短,细粒度没了。

结果?多吐比特,违背entropy理论。

解码端的暗伤

解码也有坑:

fn decode_bit(probability: f32) -> bool {
    let mid = left + ((right - left) as f32 * probability) as u32;
    if x <= mid {
        right = mid;
        bit = false;
    } else {
        left = mid + 1;
        bit = true;
    }
    
    while left >> 24 == right >> 24 {
        left <<= 8;
        right = (right << 8) | 0xff;
        x = (x << 8) | (bytes.next().unwrap() as u32);
    }
    
    bit
}

解码追三个变量:left、right和x(当前码值)。数学上,只需两样:区间长度(right - left)和点位(x - left)。

为啥三个?就为那while循环提精度。必须知道left/right绝对位置,才能查顶字节。

这耦合带来麻烦:

  • 寄存器压力大
  • 编译器优化难
  • 代码难琢磨

明明只该看区间大小,非得管位置。

怎么破?

改思路:别按顶字节相同吐(依赖偏移),改成纯看区间长度(无关偏移)。

听着简单,得重调整个编码解码循环。回报?压缩不浪费比特,解码更简更快。

为啥NameOcean在意?

我们在NameOcean帮开发者搞AI应用,用Vibe Hosting;也优化高性能系统。不管云存储压数据、API payload瘦身,还是大数据智能处理,这些压缩基础都关键。

很多人抄现成库,不知优缺点。压缩比升5-10%,小事?PB级操作或百万API请求时,雪球就大了。

大道理:课本代码不一定完美。多挖挖,懂假设,找不对称。牛工程师不只用算法,还懂边界。


云上性能应用,基础设施抉择会滚雪球。小算法优化,乘以百万请求,效果爆表。想调栈?细节决定成败。

Read in other languages:

RU BG EL CS UZ TR SV FI RO PT PL NB NL HU IT FR ES DE DA EN