Google FlatBuffers 跨平台序列化工具

作者:Bin Liu

1. 什么是FlatBuffers

Google发布了FlatBuffers,一个跨平台,提供了C++/Java接口,注重性能和资源使用的序列化(Serialization)类库。
尤其是FlatBuffers更适用移动设备,他们要求更高的新能,更低的资源需求(内存、带宽、CPU等)。

1.1. 它的特点如下:

  • 不需要打包/解包。它的结构化数据都以二进制形式保存,不需要数据解析过程,数据也可以方便传递。
  • 省内存、性能好(见附录1
  • 强类型系统,在编译阶段就能预防一些bug的产生
  • 跨平台(C++11/Java)
  • 等等。

1.2. 和Protocol Buffers的不同之处

FlatBuffers和Protocol Buffers很像,他们的最大不同点是在使用具体的数据之前,FlatBuffers不需要解析/解包的过程。

1.3. 和JSON的不同之处

JSON作为数据交换格式,被广泛用户各种动态语言之间(当然也包括静态语言)。它的有点事易于理解(可读性好),同时它的最大的缺点那就是解析时的性能问题了。而且因为它的动态类型特点,你的代码可能还需要多写好多类型、数据检查逻辑。

2. FlatBuffers的使用方法

简单来说使用FlatBuffers需要遵循以下步骤。

  1. 编写一个用来定义数据结构的schema(IDL,接口定义)文件
  2. 使用FlatBuffer编译器flatc生成数据结构源代码(C++头文件或者Java类)
  3. 使用FlatBufferBuilder类创建flat的二进制buffer
  4. 保存或者发送buffer
  5. 接收并buffer并读取数据内容

这里是一个简单的例子。

// monster.fbs

namespace MyGame;

enum Color : byte { Red = 1, Green, Blue }

union Any { Monster, Weapon, Pickup }

struct Vec3 {
  x:float;
  y:float;
  z:float;
}

table Monster {
  pos:Vec3;
  mana:short = 150;
  hp:short = 100;
  name:string;
  friendly:bool = false (deprecated, priority: 1);
  inventory:[ubyte];
  color:Color = Blue;
  test:Any;
}

root_type Monster;

将上述代码保存为monster.fbs之后,即可使用flatc来“编译了”。

生成的Java文件有如下代码(Java的使用方法有点怪怪的,估计是作者的C++背景太强了?)。


// 从byte数组读取Monster结构的数据
ByteBuffer bb = ByteBuffer.wrap(data);
Monster monster = Monster.getRootAsMonster(bb);

short hp = monster.hp();
Vec3 pos = monster.pos();

// 这样创建Monster结构的数据
FlatBufferBuilder fbb = new FlatBufferBuilder();

// 创建字符串数据
int str = fbb.createString("MyMonster");

// 创建table结构的数据
Monster.startMonster(fbb);
Monster.addPos(fbb, Vec3.createVec3(fbb, 1.0f, 2.0f, 3.0f, 3.0, (byte)4, (short)5, (byte)6));
Monster.addHp(fbb, (short)80);
Monster.addName(fbb, str);
Monster.addInventory(fbb, inv);
Monster.addTest_type(fbb, (byte)1);
Monster.addTest(fbb, mon2);
Monster.addTest4(fbb, test4s);
int mon = Monster.endMonster(fbb);

// 增加各Vector结构的数据
Monster.startInventoryVector(fbb, 5);
for (byte i = 4; i >=0; i--) fbb.addByte(i);
int inv = fbb.endVector();

附录:

[1] 性能数据,来源于http://google.github.io/flatbuffers/md__benchmarks.html


FlatBuffers (binary)
Protocol Buffers LITE Rapid JSON FlatBuffers (JSON)
Decode + Traverse + Dealloc (1 million times, seconds) 0.08 305 583 105
Decode / Traverse / Dealloc (breakdown) 0 / 0.08 / 0 220 / 3.6 / 81 294 / 0.9 / 287 70 / 0.08 / 35
Encode (1 million times, seconds) 3.2 185 650 169
Wire format size (normal / zlib, bytes) 344 / 220 228 / 174 1475 / 322 1029 / 298
Memory needed to store decoded wire (bytes / blocks) 0 / 0 760 / 20 65689 / 40 328 / 1
Transient memory allocated during decode (KB) 0 1 131 4
Generated source code size (KB) 4 61 0 4
Field access in handwritten traversal code accessors accessors manual error checking accessors
Library source code (KB) 15 some subset of 3800 87 43

[2] 源代码在GitHub:https://github.com/google/flatbuffers



Posted in Tech Tagged with: , , ,

无觅相关文章插件,快速提升流量