uint16array 本身不压缩数据,但通过对其有效位宽(如12-bit)对齐、零拷贝存储及位运算支持,为rle或delta+bit-packing等后续压缩奠定基础;需依传感器实际分辨率确定n,再按packsper16 = ⌊16/n⌋打包以实现空间压缩。

Uint16Array 本身不提供压缩功能,但它能高效存储固定位宽(≤16 bit)的传感器原始离散数据,为后续按位压缩(如 RLE、Delta + Bit-packing)打下基础。关键在于:**对齐位宽、避免类型转换开销、预留压缩接口**。
明确传感器数据的实际位宽
多数低功耗传感器(如温度、加速度计、ADC采样)输出有效位宽远小于 16 bit(例如 12-bit 温度值、10-bit 光强、14-bit 压力)。若盲目用 Uint16Array 存每个样本,会浪费 2–6 bit/样本空间。
- 先确认传感器 datasheet 中的输出分辨率(如 “12-bit LSB = 0.0625°C”)
- 实测采集一批原始值,用
Math.max()和Math.min()验证动态范围是否真在0–4095内 - 若始终 ≤ 2n−1(n ≤ 16),就可将 n 定为“有效位宽”,这是后续位压缩的前提
用 Uint16Array 做紧凑、零拷贝的原始容器
相比 Array 或 Int32Array,Uint16Array 在内存布局和访问速度上更优,且天然支持位运算:
- 直接分配:
const buffer = new Uint16Array(sampleCount) - 从 I2C/SPI ArrayBuffer 直接视图映射(无拷贝):
new Uint16Array(rawBuffer, byteOffset, length) - 写入时不做范围检查(比普通数组快),但需确保值 ∈ [0, 65535] —— 可用
value & 0xFFFF截断高位 - 读取后可立即用于位操作,例如提取低 12 位:
sample & 0x0FFF
配合位打包(Bit-packing)实现真正压缩
单靠 Uint16Array 不省空间;必须把多个 n-bit 样本“塞进”更少的 uint16 单元中。例如 12-bit 数据,每 8 个样本共 96 bit → 恰好占 6 个 Uint16(96 ÷ 16 = 6),压缩率 75%。
- 预计算打包密度:
packsPer16 = Math.floor(16 / n),余数位宽remainder = 16 % n - 写入时用位移+或操作累积到当前 uint16 单元;满则存入数组并重置
- 解包时用掩码(
(1 )和右移提取每个样本 - 推荐封装为
BitPackedBuffer(n)类,内部持Uint16Array,暴露push(value)和at(index)
结合 Delta 编码进一步降低熵值
传感器数据常具强时间相关性(如温度缓变、振动周期采样)。先做差分再打包,能显著提升后续 Huffman 或 LZ77 效果:
- 首样本存原值,后续存
current - previous(有符号) - 差值通常远小于原始值,有效位宽骤降(如 12-bit 原值 → 差值集中在 −64~+63,仅需 7 bit)
- 用
Int16Array存差值更自然,但若坚持全Uint16Array,可用偏移编码:存delta + 0x8000,解包时再减 - Delta 后再做位打包,压缩率常比纯原始打包高 2–5×
不复杂但容易忽略:位宽对齐是压缩的起点,Uint16Array 是最轻量的载体,而真正压缩靠的是你如何组织它的比特——不是存得“多”,而是存得“密”。










