FlatBuffers 是Google推出的一个跨平台、跨语言的序列化和反序列化库,主要用于游戏以及对性能要求较高的系统中,例如RPC框架、保存端测推理的模型文件等(如TFLite)。端测不同于服务器,内存和算力等资源相对于服务器十分有限,想要缩短整个推理的时间和内存消耗,模型加载的阶段也需要考虑。FlatBuffers可以只使用一块内存进行解析,恰好满足这些要求。其使用步骤如下:
- 下载源码编译得到一个编译该库指定的IDL(Interface Definition Language)所定义的Schema的编译器
flatc
; - 按照IDL的语法编写Schema;
- 使用第一步编译出的
flatc
编译第二步写出的Schema,得到对应语言的序列化和反序列化接口; - 使用第三步得到的接口进行序列化和反序列化。
具体使用方法参考官方文档即可。一般情况下,我们只需要知道FlatBuffers这个库是怎么使用的就够了,并不需要知道我们编写的Schema是如何被编译生成对应语言的接口的。
但是有意思的是,FlatBuffers包含了两个我感兴趣的东西:一个是它序列化数据的时候的思想,之前在FlatBuffer内部解析原理简介一文中有做过总结;另一个就是它的编译器。
俗话说麻雀虽小五脏俱全,作为一个编译器,虽然相比于GCC、LLVM等它非常简单,但是它的代码中对于词法分析、语法分析以及代码生成等都有体现。
1. 工作流程
flatc
的入口位于flatbuffers/src/flatc_main.cpp
中,其具体工作流程如图1所示。整个工作流程可以分为三部分:
- 解析命令行、初始化;
- 对源文件进行解析,涉及词法分析和语法分析,这两个阶段是合并在一起的;
- 目标语言的代码生成。