简介¶
序列化是指将内存中的对象持久化。比如讲对象保存到磁盘。反过来从二进制流恢复到内存称为反序列化。 序列化技术也广泛用于网络传输(如 RPC)、多进程通信。
序列化离我们并不遥远, 日常开发过程中,很多时候我们意识不到自己正在使用序列化,甚至在创建序列化协议。
日常序列化¶
这是一个常见的例子。
我们要保存一批语料,每一条有三个字段: 领域、句子、分类。 最先想到的大概就是使用逗号分隔字段, 保存到文件中。
corpus.txt:
金融,昨天上证指数又跌了,1
计算机,PHP是世界上最好的语言,0
科技,GPT-3消耗资源很多,2
然后,把这个文本交给业务方用, 一切都很顺利。 在这个场景中, 涉及到一些概念。
我们自定义了专用的序列化协议
尽管这个协议很简单,而且很不完美,但是它能满足业务需求。
这个序列化协议不是 schema-less 的
这份数据本身并不带有格式,要知道每个字段含义,必须提供 领域、句子、分类 这个 schema 才知道具体怎么解释语料。
而这个 schema 也是不明确的,比如没有明确说明 第三个字段是 int 类型还是 string 类型。 只能靠人观察。
困境¶
方案的缺陷: 当……
句子中有逗号¶
这是很明显的缺陷,也有很多种解决方法。
调整字段的顺序,把长文本类放在最后:
其他,3,我喜欢苹果,还喜欢西瓜
这是一种规避方案,固定解释前两个无歧义字段,剩下的都当作文本处理。
引入斜杠转义逗号:
\,
, 感觉没几个人有这耐性…… , 因为这意味着你还要继续实现转义斜杠:\\
,还有预料不到的歧义逻辑。使用 CSV。 嗯…… 反正都是逗号分隔。
坏处就是,你要找一个csv解析库, 顺便学一学它的用法。
使用 json。
句子中有换行¶
这个问题, 使用 csv 也解决不了, 建议用 json 或者 Excel。
schema-less¶
你幸苦制作了一批语料,两个月之后, 因为记不起schema而不知道怎么使用,这是一件很恼火的事情。
csv 数据某种程度上说是自描述 (schema-less) 的, 可以通过表头表示每一列的含义,问题是 csv 的表头并不是强制的。
所以,这里我还是推荐使用 JSON:
- schema-less 。
- 可以表示复杂数据,如 list-map 之间相互嵌套。
- 具有类型的概念。如 string、number、bool、null
如何解决¶
我还是推荐 json , 对 nlp 来说,它够用了, 而且 json 是最容易使用和 debug 的无歧义序列化方案。
但要bb一句: 在其他领域,json 通常并不是好的选择。 真正的生产环境的(非文本)序列化场景,有很多其他(二进制)序列化框架可供选择。
序列化框架¶
选择序列化框架的时候,有几个指标可以考虑。
- 是否人可阅读。即文本还是二进制类型的序列化。
- 解码速度
- 编码速度
- 数据编码后大小。这对网络IO有影响。
有很多网上的性能评测可以参考, 只不过把它们用在自己的业务场景性能如何就是另外一回事了,不能尽信。
根据 数据种类、要求的特性、传输方式、server/client性能 的不同, 对序列化框架的选择也有很大影响。
本章节是入门教程,主要介绍各个序列化框架的内部实现。 以便在编码过程中对序列化框架做出正确的选择。