FlatBuffers快速入门

FlatBuffers简介

FlatBuffers是一个开源的、跨平台的、高效的、提供了C++/Java接口的序列化工具库。它是Google专门为游戏开发或其他性能敏感的应用程序需求而创建。尤其更适用于移动平台,这些平台上内存大小及带宽相比桌面系统都是受限的,而应用程序比如游戏又有更高的性能要求。它将序列化数据存储在缓存中,这些数据既可以存储在文件中,又可以通过网络原样传输,而不需要任何解析开销。

特点

  1. 对序列化数据的访问不需要打包和拆包——它将序列化数据存储在缓存中,这些数据既可以存储在文件中,又可以通过网络原样传输,而没有任何解析开销;
  2. 内存效率和速度——访问数据时的唯一内存需求就是缓冲区,不需要额外的内存分配。 这里可查看详细的 基准测试
  3. 扩展性、灵活性——它支持的可选字段意味着不仅能获得很好的前向/后向兼容性(对于长生命周期的游戏来说尤其重要,因为不需要每个新版本都更新所有数据);
  4. 最小代码依赖——仅仅需要自动生成的少量代码和一个单一的头文件依赖,很容易集成到现有系统中。再次,看基准部分细节;
  5. 强类型设计——尽可能使错误出现在编译期,而不是等到运行期才手动检查和修正;
  6. 使用简单——生成的C++代码提供了简单的访问和构造接口;而且如果需要,通过一个可选功能可以用来在运行时高效解析Schema和类JSON格式的文本;
  7. 跨平台——支持C++11、Java,而不需要任何依赖库;在最新的gcc、clang、vs2010等编译器上工作良好;

存储结构

参考FaceBook的文档,假设我们有一个Person类定义如下:

图-1

假设有一个叫John的人,那么此Person对象在FlatBuffer中物理存储结构简化图如下,

图-2

1、每一个存储在FlatBuffer中的对象,被分割成2部分:中心点(Pivot Point)左边的元数据(vtable)和中心点右边的真实数据。
2、每个字段都对应vtable中的一个槽(slot),它存储了那个字段的真实数据的偏移量。例如,John的vtable的第一个槽的值是1,表明John的名字被存储在John的中心点右边的一个字节的位置上。
3、如果一个字段是一个对象,那么它在vtable中的偏移量会指向子对象的中心点。比如,John的vtable中第三个槽指向Mary的中心点。
4、要表明某个字段现在没有数据,可以在vtable对应的槽中使用偏移量0来标注。

Schema语言简介

Schema语言(即IDL)的语法与C语言家族、AIDL很类似。

Table

Tables是在FlatBuffers中定义对象的主要方式,如下图所示,每一个字段都是可选的,可配置默认值(如果忽略的话,默认是0/NULL)。

图-3

Structs

Structs与Table类似,不同点如下:
1.无默认值,且字段不能增加或被废弃(deprecated)
2.Struct只能包含标量或者其他struct
如果非常确定数据结构不会发生任何变化,那么就可以使用struct。Struct使用的内存比Table少,并且读取时比Table更快(它们通常被以in-line的方式存储在它们的父对象中,并且不适用virtual table)
Union、Enum功能与C语言类似

版本兼容

FlatBuffers具备良好的向前/向后兼容性,需要遵守以下规则:
1.如果要在schema中添加新字段,只能在table的末尾进行添加
2.如果不再使用某些字段了,不能从schema中删除它们;可以选择不再把它们写入到你的数据中,或者你通过deprecated来声明该字段不再使用,不过这样会使编译器不在产生该字段的代码,故存在一定的代码破坏性。

假设服务器端更新了协议,新增了一个字段,而客户端并未更新,那么当客户端收到服务器的数据时,新增的字段对客户端而言等同于没有增加,客户端不会解析新增的字段,保证了向前兼容性。

如果服务器协议回滚到一个低版本,那么当客户端收到服务器的数据进行解析时,客户端相较于服务端的新增字段,将会采用默认值,保证了向后兼容性。

更多版本控制细节,请参考Schemas and version control

支持的数据类型

内建标量:

图-4

内建非标量类型:
1.Vector ,其他数据类型的Vector (矢量),不支持内嵌
2.string,只能存储UTF-8或者7-bit ASCII。如果需要存储其他编码的文本,或者通用二进制数据,请使用vector([byte]或者[ubyte])
3.References,对其他table、struct、enum或者union的引用
更多关于编写Schema的信息,请参考Writing Schema

FlatBuffer使用步骤

1.编写Schema文件
2.使用FlatBuffers编译器生成java bean 文件,执行命令:
flatc --java samples/monster.fbs
编译器下载地址
3.编译FlatBuffers的java库,下载flatbuffers源码,进入目录执行mvn package,选择Target目录的完整jar包(第一个)
4.在Android工程中引入FlatBuffers的java库及编译器生成的java bean文件。
5.使用FlatBufferBuilder构造一个ByteBuffer(序列化对象),保存或者发送该Buffer。
6.读取该Buffer,通过getRootAsXXX可反序列化得到其代表的对象。
关于FlatBuffers可读性差的问题,可通过执行命令:
flatc --json person.fbs --raw-binary -- flat.bin
直接将二进制文件转换为json格式的文件,解决可读性差的问题

VS Java Serializable

对比测试序列化与反序列化如下对象1000次所需要的执行时间,测试结果如下:

FlatBuffers序列化耗时
FlatBuffers反序列化耗时
Java序列化耗时
Java反序列化耗时

与传统的Java序列化相比,FlatBuffers在序列化及反序列化的速度上极具优势,在存储空间的占用上也具备一定的优势,节约近乎二倍的存储空间。测试Demo的对象比较简单,当序列化对象更为复杂的时候,FlatBuffers在解析速度与空间占用的优势将更为明显。
Demo下载地址

VS json

与json相比,flatbuffers具备以下优点:
1.解析速度快到飞起(json还要走一次java序列化,速度比Java序列化还慢)
2.节约空间
3.反序列化的时候无内存抖动,就一个ByteBuffer,内存占用平稳,json在反序列化的时候会产生大量临时对象,造成内存抖动。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272

推荐阅读更多精彩内容