深入浅出 FlatBuffers 原理

一 前言FlatBuffers 是一个开源的、跨平台的、高效的、提供了多种语言接口的序列化工具库。实现了与 Protocal Buffers 类似的序列化格式。主要由 Wouter van Oortmerssen 编写,并由 Google 开源。Oortmerssen 最初为 Android 游戏和注重性能的应用而开发了 FlatBuffers,现在它具有 C ++、C#、C、Go、Java、PHP、Python 和 JavaScript 的接口。高德地图数据编译增量发布使用了FlatBuffe..
摘要由CSDN通过智能技术生成

一 前言

FlatBuffers 是一个开源的、跨平台的、高效的、提供了多种语言接口的序列化工具库。实现了与 Protocal Buffers 类似的序列化格式。主要由 Wouter van Oortmerssen 编写,并由 Google 开源。Oortmerssen 最初为 Android 游戏和注重性能的应用而开发了 FlatBuffers,现在它具有 C ++、C#、C、Go、Java、PHP、Python 和 JavaScript 的接口。

高德地图数据编译增量发布使用了FlatBuffers序列化工具,借此契机对FlatBuffers原理进行研究并分享于此。本文简单介绍 FlatBuffers Scheme,通过剖析 FlatBuffers 序列化与反序列化原理,重点回答以下问题:

  • 问题1:FlatBuffers 如何做到反序列化速度极快的(或者说无需解码)。
  • 问题2:FlatBuffers 如何做到默认值不占存储空间的(Table 结构内的变量)。
  • 问题3:FlatBuffers 如何做到字节对齐的。
  • 问题4:FlatBuffers 如何做到向前向后兼容的(Struct 结构除外)。
  • 问题5:FlatBuffers 在 add 字段时有没有顺序要求(Table 结构)。
  • 问题6:FlatBuffers 如何根据 Scheme 自动生成编解码器。
  • 问题7:FlatBuffers 如何根据 Scheme 自动生成 Json。

二 FlatBuffers Scheme

FlatBuffers 通过 Scheme 文件定义数据结构,Schema 定义与其他框架使用的IDL(Interface description language)语言类似简单易懂,FlatBuffers 的 Scheme 是一种类 C 的语言(尽管 FlatBuffers 有自己的接口定义语言 Scheme 来定义要与之序列化的数据,但它也支持 Protocol Buffers 中的 .proto 格式)。下面以官方 Tutorial 中的 monster.fbs 为例进行说明:

// Example IDL file for our monster's schema.
namespace MyGame.Sample;
enum Color:byte { Red = 0, Green, Blue = 2 }
union Equipment { Weapon } // Optionally add more tables.
struct Vec3 {
  x:float;
  y:float;
  z:float;
}
table Monster {
  pos:Vec3;
  mana:short = 150;
  hp:short = 100;
  name:string;
  friendly:bool = false (deprecated);
  inventory:[ubyte];
  color:Color = Blue;
  weapons:[Weapon];
  equipped:Equipment;
  path:[Vec3];
}
table Weapon {
  name:string;
  damage:short;
}
root_type Monster;

namespace MyGame.Sample;

namespace 定义命名空间,可以定义嵌套的命名空间,用 . 分割。

enum Color:byte { Red = 0, Green, Blue = 2 };

enum 定义枚举类型。和常规的枚举类稍有不同的地方是可以定义类型。比如这里的 Color 是 byte 类型。enum 字段只能新增,不能废弃。

union Equipment {Weapon} // Optionally add more tables

union 类似 C/C++ 中的概念,一个 union 中可以放置多种类型,共同使用一个内存区域。这里的使用是互斥的,即这块内存区域只能由其中一种类型使用。相对 struct 来说比较节省内存。union 跟 enum 比较类似,但是 union 包含的是 table,enum 包含的是 scalar 或者 struct。union 也只能作为 table 的一部分,不能作 root type。

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

struct 所有字段都是必填的,因此没有默认值。字段也不能添加或者废弃,且只能包含标量或者其他 struct。struct 主要用于数据结构不会发生改变的场景,相对 table 使用更少的内存,lookup 的时候速度更快(struct 保存在父 table 中,不需要使用 vtable)。

table Monster{};

table 是在 FlatBuffers 中定义对象的主要方式,由一个名称(这里是 Monster)和一个字段列表组成。可以包含上面定义的所有类型。每个字段(Field)包括名称、类型和默认值三部分;每个字段都有默认值,如果没有明确写出则默认为

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值