Google序列化库FlatBuffers 1.1发布,及与protobuf的比较
个人总结:
FlatBuffer相对于Protobuffer来讲,优势如下:
1. 由于省去了编解码的过程,所以从速度上快于Protobuffer,个人测试结果100w次编解码,编码上FlatBuffer 优势不明显,解码上优势明显
2. FlatBuffer的格式文件定义上比Protobuffer格式更丰富
3. 使用方便,直接一个头文件就能搞定,这点很赞
劣势:
1. FlatBuffer的使用上不如Protobuffer方便,创建类型多了一次转换,这和FlatBuffer提升性能有关
2. FlatBuffer的格式定义文件比较灵活,不如Protobuffer直观性好
3. 目前项目的稳定度上略为欠缺,Github上issuse还不少
另外:
1. FB中的Table中field都为optional,可以指定default value,如果not optional and no defaults,可以使用struct
2. PB中定义message的时候可以使用opitional和required 进行指定
如果对于性能没有迫切要求和通信消息量不大的情况,两者都可以选择。
FlatBuffers 1.1版本下载地址:
https://github.com/google/flatbuffers/releases
FlatBuffers项目主页:
http://google.github.io/flatbuffers/index.html
项目在GitHub上的托管地址:
https://github.com/google/flatbuffers
经过几个月开发,FlatBuffers 1.1版本更新。这次的更新包含:
-
对Java API进行了广泛的检修
-
out-of-the-box支持C#和Go
-
一个可选的校对器,使FlatBuffers在不可信的情况下变得实用
-
原型解析更容易从协议缓冲区迁移
-
字段ID可选手动分配
-
通过对一个键字段二进制查询的字典功能
-
bug修复和其他的改进
FlatBuffers与protobuf性能比较
http://blog.csdn.net/menggucaoyuan/article/details/34409433
......从以上数据看出,在内存空间占用这个指标上,FlatBuffers占用的内存空间比protobuf多了两倍。序列化时二者的cpu计算时间FB比PB快了3000ms左右,反序列化时二者的cpu计算时间FB比PB快了9000ms左右。FB在计算时间上占优势,而PB则在内存空间上占优(相比FB,这也正是它计算时间比较慢的原因)。
上面的测试环境是在公司的linux server端和我自己的mac pro分别进行的。请手机端开发者自己也在手机端进行下测试, 应该能得到类似的结果。Google宣称FB适合游戏开发是有道理的,如果在乎计算时间我想它也适用于后台开发。
另外,FB大量使用了C++11的语法,其从idl生成的代码接口不如protubuf友好。不过相比使用protobuf时的一堆头文件和占18M之多的lib库,FlatBuffers仅仅一个"flatbuffers/flatbuffers.h"就足够了。
一. 什么是Google FlatBuffers
FlatBuffers是一个开源的、跨平台的、高效的、提供了C++/Java接口的序列化工具库。它是Google专门为游戏开发或其他性能敏感的应用程序需求而创建。尤其更适用于移动平台,这些平台上内存大小及带宽相比桌面系统都是受限的,而应用程序比如游戏又有更高的性能要求。它将序列化数据存储在缓存中,这些数据既可以存储在文件中,又可以通过网络原样传输,而不需要任何解析开销。
二. 为什么要使用Google FlatBuffers
对序列化数据的访问不需要打包和拆包——它将序列化数据存储在缓存中,这些数据既可以存储在文件中,又可以通过网络原样传输,而没有任何解析开销;
-
内存效率和速度——访问数据时的唯一内存需求就是缓冲区,不需要额外的内存分配。 这里可查看详细的 基准测试;
-
扩展性、灵活性——它支持的可选字段意味着不仅能获得很好的前向/后向兼容性(对于长生命周期的游戏来说尤其重要,因为不需要每个新版本都更新所有数据);
-
最小代码依赖——仅仅需要自动生成的少量代码和一个单一的头文件依赖,很容易集成到现有系统中。再次,看基准部分细节;
-
强类型设计——尽可能使错误出现在编译期,而不是等到运行期才手动检查和修正;
-
使用简单——生成的C++代码提供了简单的访问和构造接口;而且如果需要,通过一个可选功能可以用来在运行时高效解析Schema和类JSON格式的文本;
-
跨平台——支持C++11、Java,而不需要任何依赖库;在最新的gcc、clang、vs2010等编译器上工作良好;
三. 为什么不使用Protocol Buffers的,或者JSON
Protocol Buffers的确和FlatBuffers比较类似,但其主要区别在于FlatBuffers在访问数据前不需要解析/拆包这一步。 而且Protocol Buffers既没有可选的文本导入/导出功能,也没有Schemas语法特性(比如union)。
JSON是非常可读的,而且当和动态类型语言(如JavaScript)一起使用时非常方便。然而在静态类型语言中序列化数据时,JSON不但具有运行效率低的明显缺点,而且会让你写更多的代码来访问数据(这个与直觉相反)。
四. 内建的数据类型
8 bit: byte ubyte bool
16 bit: short ushort
32 bit: int uint float
64 bit: long ulong double
Vector of any other type (denoted with [type]). Nesting vectors is not supported, instead you can wrap the inner vector in a table.
string, which may only hold UTF-8 or 7-bit ASCII. For other text encodings or general binary data use vectors ( [byte] or [ubyte]) instead.
References to other tables or structs, enums or unions.
五. 如何使用
-
编写一个用来定义你想序列化的数据的schema文件(又称IDL),数据类型可以是各种大小的int、float,或者是string、array,或者另一对象的引用,甚至是对象集合;
-
各个数据属性都是可选的,且可以设置默认值。
-
使用FlatBuffer编译器flatc生成C++头文件或者Java类,生成的代码里额外提供了访问、构造序列化数据的辅助类。生成的代码仅仅依赖flatbuffers.h;请看 如何生成;
-
使用FlatBufferBuilder类构造一个二进制buffer。你可以向这个buffer里循环添加各种对象,而且很简单,就是一个单一函数调用;
-
保存或者发送该buffer
-
当再次读取该buffer时,你可以得到这个buffer根对象的指针,然后就可以简单的就地读取数据内容;