简单易懂的时序数据压缩算法分析

背景

今年在公司内部主导了两个的行情数据系统的构建,两者均使用到了常见的时序数据压缩算法。

这里简单总结一下过程中积累的一些经验。

让我们先来思考一个问题:压缩算法生效的前提是什么?

数据本身至少要符合以下两种特性其一:

  • 数据存在冗余
  • 数据符合特定的概率分布

在时序数据领域,数据冗余度与相似度较高,因此天生适合进行压缩。

但对于不同类型的数据,其所适用的压缩算法也大相径庭。

下面我们逐一介绍这些数据相应的压缩算法。

整数

整型数据是构建各种应用的基石,时序型应用也不例外。

在行情数据中,存在大量的整型数据,例如:逐笔成交中的时间戳、成交量。

根据压缩算法的不同,可以将整型数据分为以下 3 类:

  • 无符号整型 —— Varint
  • 有符号整型 —— ZigZag
  • 时间戳 —— Delta2 + Simple8b

Varint

一个 32 位的无符号整型能表达 0 - 4294967295 之间的任意数字

但这些数字在日常生活中出现的概率并不是均匀分布的,一个著名的例子是 本福特定律 ,该定律常被用于辨别数据的真伪。

通常情况下,较小的数字出现的概率会高于极大的数据。

以年龄为例,无论人口如何分布,大部分人的年龄都位于 0 ~ 100 之间。

表示 128 仅需要 7bit 足矣,如果使用 32bit 的无符号整型进行存储,意味着至少浪费了 24bit。

幸运的是,我们能通过一种自适应编码方式来减少这种浪费 —— Varint。

public class VarIntCodec {

    static int encodeInt(int v, byte[] bytes, int offset) {
        if (v < 0) {
            throw new IllegalStateException();
        } else if (v < 128) {
            bytes[offset++] = (byte) v;
        } else if (v < 16384) {
            bytes[offset++] = (byte) (v | 0x80);
            bytes[offset++] = (byte) ((v >>> 7) & 0x7F);
        } else if (v < 2097152) {
            bytes[offset++] = (byte) (v | 0x80);
            bytes[offset++] = (byte) ((v >>> 7) | 0x80);
            bytes[offset++] = (byte) (v >>> 14);
        } else if (v < 268435456) {
            bytes[offset++] = (byte) (v | 0x80);
            bytes[offset++] = (byte) ((v >>> 7) | 0x80);
            bytes[offset++] = (byte) ((v >>> 14) | 0x80);
            bytes[offset++] = (byte) (v >>> 21);
        } else {
            bytes[offset++] = (byte) (v | 0x80);
            bytes[offset++] = (byte) ((v >>> 7) | 0x80);
            bytes[offset++] = (byte) ((v >>> 14) | 0x80);
            bytes[offset++] = (byte) ((v >>> 21) | 0x80);
            bytes[offset++] = (byte) (v >>> 28);
        }
        return offset;
    }

    static int decodeInt(byte[] bytes, int[] offset) {
        int val;
        int off = offset[0];
        byte b0, b1, b2, b3;
        if ((b0 = bytes[off++]) >= 0) {
            val = b0;
        } else if ((b1 = bytes[off++]) >&
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值