无论使用何种编程语言,json格式的数据已被广泛应用,不论是数据的传输还是存储,在很多应用场景下,你可能想进一步地压缩JSON字符串的长度,以提升传输效率,如果你使用的是nosql数据库,你可能想进一步的压缩json字符串的长度来节省你的存储空间,接下来,我将介绍一下目前最常用的json数据压缩技术(CJSON和HPack)的实现(文章最后有彩蛋哦)。
一、CJSON
CJSON 的压缩算法, 主要是将资料抽离成 Template 与 Value,节省掉重复的 "Key 值".
原数据:
[
{ "x": 100,
"y": 100
}, { "x": 100,
"y": 100,
"width": 200,
"height": 150
},
{},
]
压缩之后:
{
"templates": [
[0, "x", "y"], [1,"width", "height"]
],
"values": [
{ "values": [ 1, 100, 100 ] },
{ "values": [2, 100, 100, 200,150 ] },
{}
]
}
二、HPack
HPack 的压缩算法, 也是将 Key, Value 抽离, 阵列中第一个值, 就是 HPack 的 Template, 后面依序就是 Value.
原数据:
[{
name : "Andrea",
age : 31,
gender : "Male",
skilled : true
}, {
name : "Eva",
age : 27,
gender : "Female",
skilled : true
}, {
name : "Daniele",
age : 26,
gender : "Male",
skilled: false
}]
压缩之后:
[["name","age","gender","skilled"],["Andrea",31,"Male",true],["Eva",27,"Female",true],["Daniele",26,"Male",false]]
结论
两种方法都是主要讲json 的 键抽出来统一建成索引,只是最后的格式不同,HPack 简化后的格式比CJSON 少了许多字符,所以HPack 的压缩效率比较高, 如果 JSON 内容太少, CJSON的资料可能反而会比较多。
三、彩蛋
我在研究开源性能分析工具pinpoint的源码时,发现了里面有使用一种压缩比更高的做法,
例如:
原数据:
{
name : "Andrea",
age : 31,
gender : "Male",
skilled : true
}
压缩后的示意图如下:
压缩之后的数据变成了一串二进制数据,其中 name 和 gender 由于是 string 类型,长度不定,故使用他们的第一个四位数作为表示这个该name 对应值“Andrea”的二进制长度,其他类型的数据取值如下图的API:
这样的做法可以被认为是一种加密性质的压缩,如果数据接收方不知道数据结构,是无法直接解析出目标值的。需要数据发送发和数据接收方约定好字段的结构。
从上面的例子中,我们发现,CJSO和HPack 都只是节省了 json数据键的大小,但是里面的中括号和引号都无用且大量冗余,我上面介绍的这种压缩方法使用起来复杂度可能高一点,但是压缩比可以比上面的两种更好一些,不管是作为存储还是作为数据的传输,都可以节省大量的资源。