在观看谷歌发布的视频时,发现视频将json或者xml成为网络传输中的horrible type。这让天天和json打交道的我感觉很疑惑,后面提到了谷歌的FlatBuffers,仿佛打开新世界的大门。虽然我现在开发的业务json的解析并不是瓶颈,但是多学点东西总不是坏事,本篇文章就从源码角度分析下flatbuffer的原理,相信大家看完也就知道flatbuffer快在哪和慢在哪了。
首先我们知道json是基于字符串和各种特殊字符进行解析的,这也就意味着我们在解析的时候需要将数据先整理成标准的json格式,这其中的内存和时间开销较大。而flatbuffers是一种基于二进制数据,根据偏移量进行解析。也就是说省略了解析过程中的各种时间和内存损耗,映衬了名字中的flat。
本文从官方给出的示例结合源码进行分析,由于源码较少,大家可以下载后编进自己项目中即可。
首先我们看,创建一个FlatBufferBuilder做了什么。
public FlatBufferBuilder(int initial_size, ByteBufferFactory bb_factory,
ByteBuffer existing_bb, Utf8 utf8) {
if (initial_size <= 0) {
initial_size = DEFAULT_BUFFER_SIZE;
}
// 这里的bb_factory是一个单例,用于申请bytebuffer的空间
this.bb_factory = bb_factory;
if (existing_bb != null) {
bb = existing_bb;
bb.clear();
bb.order(ByteOrder.LITTLE_ENDIAN);
} else {
// 这里申请了缓冲区
bb = bb_factory.newByteBuffer(initial_size);
}
this.utf8 = utf8;
// 由于基于偏移量进行存储和解析,需要时刻知道缓冲区大小以及被占用的大小
space = bb.capacity();
}
这时候我们拿到了builder对象,之后对于数据的存放均基于这个对象。也就是放到我们申请的缓冲区中。
我们以builder.createString()为例
public int createString(CharSequence s) {
// flatbuffers支持的字符串均为UTF-8编码,对于字符串的处理的性能低
// 也是因为这里有解码转码的过程
int length = utf8.encodedLength(s)