为什么Proto Buf高效
序列化和反序列化
大家接触的比较多的是java自带的序列化工具,例如我们要对象数据进行持久化到硬盘或者通过网络传输到对端主机上,所以我们需要通过某种序列化工具将数据转化成一种特定数据结构,并且对端或者从磁盘读取时能够按照这种结构解析形成对象。 序列化:对象—>特定结构的二进制串 反序列化:二进制串–>对象。
序列化工具有:Hessian(主要还是java,其他部分语言支持)、JSON、XML、java自带序列化(不能跨语言)、Proto Buf(跨语言)
一个好的序列化工具能够保证空间利用率高,节省网络资源并且能提高解析速率,目前确实存在这样一款很好的序列化工具那就是下面将的Google Proto Buf
Proto Buf 数据结构详解
PB(Proto Buffer) 序列化效率高?
PB序列化和反序列化速度比JSON、XML快20-100倍
1、自带proto编译其能快速进行序列化和反序列化
2、精简的数据结构,就是说同一个对象使用PB序列化成的字节数组会比其他序列化的字节数据更小,这样提高了传输效率和提高反序列化速度
3、语言无关性以及扩展性和兼容性好
Proto Buf 数据结构
TLV (Tag:字段唯一标识、Length:表示字段值的长度 Value:字段的值)
Tag:field_number+wire_type(指定value的类型)
Leg:如果是字符串类型,需要指定字符串的长度
Value:实际存放的数据
最关键一点是无需要传输字段名称,仅仅将字段序号放在tag中,因为proto buf 需要在两端使用同一份数据结构定义文件,通过这个数字来找对应字段。这样大大压缩了空间。
进一步精简:
对于大部分整形数据一般都占用不到4个字节,所以对于表示1-127之间数字只需一个字节进行存储,对数据进行压缩
提高解析速度:
对于json数据规范,既需要定义字段名(字段名会占用好几个字段,不固定),读取字段对应值需要根据特定字符进行匹配(因为json表示的数据并不知道值到底是占用多少个字节)
针对上面json解析速度慢,protobuf 做了以下优化,在tag中增加了value的类型,解析的boolean时候直接从后面读取1个字节,当遇到不固定长度的字符串时,需要读取Leg字段值,然后从Leg字段往后取出对应个数的字节,避免了耗时的字符串匹配。
联想到计算机中的数据结构
当你接触越来越多的技术和计算机底层实现时,发现一切都离不开数据结构,数据结构简单说就是设计一种高效的数据结构(线性结构、树、图)让我们杂乱无章、不规整的数据 网络传输更有效、存储更精简、计算更高效。
计算机操作系统中使用队列管理内存、调度进程
计算机网络中定义好一种数据(二进制串)结构(协议)能够将数据在网络中进行传输,然后在对端通过约定好的方式进行解析
例如Kafka分布式消息队列中消息的数据结构、Redis中缓存数据的各种数据结构、数据库中索引数据结构、我们一些应用服务也会涉及到各种数据的结构