私货时间到~
JSON vs Zipack
当今最流行的序列化格式无疑是JSON,但是基于文本的JSON有许多缺点,比如解析速度慢,体积较大。根本原因在于,JSON是基于文本的,只要是文本就离不开编译,只要编译就永远没有二进制格式来的快,而只有基于前缀的二进制格式能克服这些问题。经过若干个月的打磨,我设计出了一套紧凑的、无协议的二进制序列化格式Zipack用来取代JSON,为数据的存储和传输提供更好的方案。
官网:https://zipack.gitee.io/
Gitee仓库:https://gitee.com/zipack/
文件后缀名:.zipack
mime类型:application/zipack
Zipack初体验
在线体验:https://zipack.gitee.io/#demo
在官网的在线demo中,我们可以输入任意的JSON串,下面会自动生成相对应的Zipack字节串(16进制),不同的是,体积大大压缩了!事实上,Zipack采用的是变长前缀编码,简单地说,更常用的类型更短,比如0~127的正整数只占一个字节,短的字符串只需额外一个字节来表示类型和长度。
拒绝Base64,随意插入纯二进制数据
想象一下,如果想要在JSON中插入一个纯二进制数据,我们得使用Base64等手段把字节串序列化成字符串再插入JSON,但用Base64编码的后果就是,体积膨胀1/3。在Zipack中就不会出现这个问题,因为Zipack有一个基本类型就是字节串!比如在JavaScript中,我们可以这样定义一个文件对象,包括文件名,mime类型以及文件内容:
zipack.serialize({
name: 'binary-file.bin',
mime: 'application/octet-stream',
file: new ArrayBuffer(8)
})
这里我们使用的软件是zipack.js,这也是Zipack官方提供的JavaScript版本的编解码器,之前的在线demo也用的它。如果你觉得还可以,记得回来star,follow一下我的仓库哦,地址:https://gitee.com/zipack/zipack-javascript。
迷惑行为大赏:0.1和0.5的区别
只有一个特殊情况下压缩率是超过100%的,如果输入的是一个不能被2的幂整除的十进制小数,那它的Zipack值反而变大了,观察下面这2种情况:
当我们输入0.5,压缩率是100%,但输入0.1时压缩率变成167%,体积反而变大了,这是因为十进制的0.5用二进制表示为0.1,但是十进制的0.1用二进制表示就是0.00011001100110011001100110011001100110011......无限循环。这是因为0.5可以表示为1/2,分母的2的幂,但0.1无法这样表示,所以0.1无法用二进制精确地表示,小数点后面只能拖很长的一条尾巴,于是zipack的体积反而变大了。但是不用担心,在正常情况下我们存放在内存中的小数都是二进制的,不会出现这种问题。
Zipack的优势
体积更小:可以将JSON压缩至70%左右。
速度更快:基于前缀的二进制格式无须编译,比文本格式更快。
类型丰富:支持Number,String,Bool,Null,ByteArray,List,Map(字典)以及保留类型。
变长编码:根据Huffman编码,常用的类型更短,如小整数只占1个字节。
原创算法:在处理字符串和浮点数上,Zipack采用压缩率更高的编码来取代标准的UTF8和IEEE浮点数,具体原理请参考Zipack的格式规范。
自由扩展:Zipack提供保留前缀,开发者可借此添加新的类型。
流化传输:处理大数据的时候,Zipack可以无缝拼接,边传输边处理。
好啦,以上就是我给大家带来的Zipack初体验,但本文尚未涉及Zipack是如何实现的,下一期我将带给大家一篇详细的说明文来介绍Zipack的底层原理以及近乎完美的设计理念,当然你也可以去官方的Gitee仓库阅读Zipack规范:https://gitee.com/zipack/spec。如果可以科学上网的话,建议直接去Github仓库上阅读“原著”:
https://github.com/zipack/spec
最后别忘了star和follow,如果还能打赏,那将是对我对大的鼓励。