学习Protobuf,Varint是啥你真的知道么?

简介:

这篇文章,是学习Protobuf过程中偶然所得,算法简洁,篇幅较短,预计阅读时间 4 分钟,如果对您有帮助,还望不吝评价,求点赞、求评论、求转发

Varint 是什么?

早期,为了更好计算效率,我们的计算机中数值通常使用定长整型(fixed length intergers)表示。但是,微服务RPC 架构盛行的今天,定长整型就显得冗余。

在大多数计算机系统中,以4 Bytes 8 Bytes 来表示整数(Int32、Int64)。这样,为了传输一个整数1,我们需要传输00000000 00000000 00000000 00000001 32 个 bits,而有价值的数据只有 1 位,这也太浪费了吧?

为了节约网络带宽,我们需要一种更加灵活的方式传输方式。Varint(Variable length integers)便是一种用于压缩整型数值的方法,通过它可以更加灵活的表达整型数值需要的空间大小。

十进制:1
二进制:00000000 00000000 00000000 00000001
Varint:00000001

可以看到,通过使用Varint方法,我们将传输大小从4 Bytes压缩至1 Bytes,这怎么弄的呢?

Varint 的原理

编码规则

  • a.将整数的二进制按7bit分组,从低位到高位依次排列
  • b.最后一组MSB设置0,其他组的MSB设置为1

编码演示

7bit进行分组,对数组逆序设置MSB(Most Significant Bit)即可,具体如图:

image2022-3-3_21-29-55.png

解码规则

  • a.去掉MSB重新组合7bit字符列表
  • b.逆序存储7bit字符列表

Varint 编码实现(Python)

def varint_compress(zz):
    res = []
    while zz:
        if (zz >> 7) != 0:
            res.append(0x80 | (zz & 0x7F))
            zz = zz >> 7
        else:
            res.append(zz & 0x7F)
            break
    return res

获取 Varint 的长度方法

def varint_code_len(vb):
    res = 0
    while vb:
        vb >>= 7
        res += 1
    return res

Varint 解码实现(Python)

def varint_decompress(zb):
    res = 0
    offset, size = 0, len(zb)
    for i in range(size):
        if (zb[i] & 0x80) == 0x80:
            res |= (zb[i] & 0x7F) << offset
        else:
            res |= zb[i] << offset
            break
        offset += 7
    return res

总结一下

在大多数情况下,通过Varint 编码整数都有好压缩效果,但遇到负数或大整数,就不具备压缩优势了,如下:

十进制:-1
二进制:10000000 00000000 00000000 00000001
Varint:10000001 10000000 10000000 10000000 00001000

十进制:2^30
二进制:01000000 00000000 00000000 00000000
Varint:10000000 10000000 10000000 10000000 00000100

由于引入了MSB,不但没有好的压缩效果,还加大了存储,这明显不是我们想要的 那怎么办呢?ZigZag由此而生,那这个算法具体思想是怎么样的呢?请听我们下回分解

参考文档

❤️❤️❤️读者每一份热爱都是笔者前进的动力! 我是三十一,感谢各位朋友:求点赞、求评论、求转发,大家下期见!

相关文章
|
程序员 开发工具 Docker
13个程序员常用开发工具用途推荐整理
13个程序员常用开发工具用途推荐整理
332 0
|
2月前
|
弹性计算 搜索推荐 异构计算
阿里云服务器收费标准:包年包月和按量付费费用整理
阿里云服务器提供包年包月与按量付费两种模式,包年包月低至38元起/年,涵盖2核2G到8核32G多款爆款配置,轻量应用服务器享200M峰值带宽不限流量,香港节点25元/月起,GPU服务器亦有优惠,新老用户均可享大幅折扣。
627 40
|
6月前
|
安全
如何从零开始,搭建一套消防安全管理系统
在预算不多、人手有限的情况下,我们不需要追求复杂精密的系统,而是需要找准“能用、好用、用得下去”的方案。这些看似微不足道的细节,才是真正守住风险底线的关键
|
机器学习/深度学习 负载均衡 算法
深入探索Linux内核调度机制的优化策略###
本文旨在为读者揭开Linux操作系统中至关重要的一环——CPU调度机制的神秘面纱。通过深入浅出地解析其工作原理,并探讨一系列创新优化策略,本文不仅增强了技术爱好者的理论知识,更为系统管理员和软件开发者提供了实用的性能调优指南,旨在促进系统的高效运行与资源利用最大化。 ###
|
8月前
|
人工智能 JavaScript 数据安全/隐私保护
鸿蒙开发难题多到崩溃?然而 10 亿终端暗藏财富密码-卓伊凡
鸿蒙开发难题多到崩溃?然而 10 亿终端暗藏财富密码-卓伊凡
217 5
鸿蒙开发难题多到崩溃?然而 10 亿终端暗藏财富密码-卓伊凡
|
边缘计算 物联网 5G
5G小基站技术:解决室内覆盖难题
【10月更文挑战第25天】
751 5
|
机器学习/深度学习 人工智能 TensorFlow
如何将OpenCV与AI深度学习结合使用
如何将OpenCV与AI深度学习结合使用
655 1
|
存储 编译器 C语言
【C语言】关键字static——static修饰局部变量、全局变量和函数详解!
【C语言】关键字static——static修饰局部变量、全局变量和函数详解!
746 0
|
SQL 关系型数据库 MySQL
【Flask】Flask项目sqlite数据库操作(代码实现)
Flask项目sqlite数据库操作(代码实现)
|
人工智能 安全 数据安全/隐私保护
真香,一分钟N个谷歌邮箱注册成功,抓紧上车
真香,一分钟N个谷歌邮箱注册成功,抓紧上车