目录
1.序列化概念
- 序列化:把对象转换为字节序列的过程,称为对象的序列化
- 反序列化:把字节序列恢复为对象的过程 称为对象的反序列化
- 什么情况需要序列化?
- 存储数据:想把的内存中的对象状态保存到⼀个⽂件中或者存到数据库中时
- 网络传输:⽹络直接传输数据,但是⽆法直接传输对象,所以要在传输前序列化,传输完成后反序列化成对象
- 如何实现序列化?
- XML、JSON、ProtoBuf
2.ProtoBuf是什么?
- 语⾔⽆关、平台⽆关:⽀持Java、C++、Python等多种语⾔,⽀持多个平台
- 高效:比XML更小、更快、更为简单
- 扩展性、兼容性好:可以更新数据结构,⽽不影响和破坏原有的旧程序
- 相对于XML 和JSON来说,因为被编码成⼆进制,破解成本增⼤,ProtoBuf编码是相对安全的
3.ProtoBuf使用特点
- 使用步骤:
- 编写
.proto
⽂件,⽬的是为了定义结构对象(message
)及属性内容 - 使⽤
protoc
编译器编译.proto
⽂件,⽣成⼀系列接⼝代码,存放在新⽣成头⽂件和源⽂件中 - 依赖⽣成的接⼝,将编译⽣成的头⽂件包含进自己的代码中,实现对
.proto
⽂件中定义的字段进⾏设置和获取,和对message
对象进⾏序列化和反序列化
- 编写
- 总结:ProtoBuf是需要依赖通过编译⽣成的头⽂件和源⽂件来使⽤的
-
有了这种代码⽣成机制, 开发⼈员再也不⽤吭哧吭哧地编写那些协议解析的代码了
-
⼲这种活是典型的吃⼒不讨好:P
-
4.补充
1.GOOGLE_PROTOBUF_VERIFY_VERSION 宏
- 验证没有意外链接到与编译的头⽂件不兼容的库版本
- 如果检测到版本不匹配,程序将中⽌
- 注意:
- 每个
.pb.cc
⽂件在启动时都会⾃动调⽤此宏 - 在使⽤C++ Protocol Buffer库之前执⾏此宏是⼀种很好的做法,但不是绝对必要的
- 每个
2.ShutdownProtobufLibrary()
- 语法:
google::protobuf::ShutdownProtobufLibrary();
- 作用:在程序结束时调⽤
ShutdownProtobufLibrary()
,为了删除Protocol Buffer库分配的所有全局对象 - 注意:
- 对于⼤多数程序来说这是不必要的,因为该过程⽆论如何都要退出,并且操作系统将负责 回收其所有内存
- 但是,如果使⽤了内存泄漏检查程序,该程序需要释放每个最后对象,或者正在编写可以由单个进程多次加载和卸载的库,那么可能希望强制使⽤Protocol Buffers来清理所有内容
3.–decode
- 使用示例:
protoc --decode=contacts2.Contacts contacts.proto < contacts.bin
- 作用:从标准输⼊中读取给定类型的⼆进制消息,并将其以⽂本格式写⼊标准输出
- 注意:消息类型必须在
.proto
⽂件或导⼊的⽂件中定义
5.序列化能力对比验证
- 此处分别使用PB和JSON,对值完全相同的一份结构化数据进行粗略的性能测试,代码此处略
- 结果:
100次 [pb序列化]耗时:0.342ms. 序列化后的⼤⼩:278 100次 [pb反序列化]耗时:0.435ms. 100次 [json序列化]耗时:1.306ms. 序列化后的⼤⼩:567 100次 [json反序列化]耗时:0.926ms. 1000次 [pb序列化]耗时:3.59ms. 序列化后的⼤⼩:278 1000次 [pb反序列化]耗时:5.069ms. 1000次 [json序列化]耗时:11.582ms. 序列化后的⼤⼩:567 1000次 [json反序列化]耗时:9.289ms. 10000次 [pb序列化]耗时:34.386ms. 序列化后的⼤⼩:278 10000次 [pb反序列化]耗时:45.96ms. 10000次 [json序列化]耗时:115.76ms. 序列化后的⼤⼩:567 10000次 [json反序列化]耗时:91.046ms. 100000次 [pb序列化]耗时:349.937ms. 序列化后的⼤⼩:278 100000次 [pb反序列化]耗时:428.366ms. 100000次 [json序列化]耗时:1150.54ms. 序列化后的⼤⼩:567 100000次 [json反序列化]耗时:904.58ms.
- 结论:
- 编解码性能:ProtoBuf的编码解码性能,⽐JSON⾼出2-4倍
- 内存占⽤:ProtoBuf的内存占⽤只有JSON的约1/2
6.总结
-
JSON、XML、ProtoBuf对比
-
总结:
- XML、JSON、ProtoBuf都具有数据结构化和数据序列化的能⼒
- XML、JSON更注重数据结构化,关注可读性和语义表达能⼒
- ProtoBuf更注重数据序列化,关注效率、空间、速度,可读性差,语义表达能⼒不⾜,为保证极致的效率,会舍弃⼀部分元信息
- ProtoBuf的应⽤场景更为明确,XML、JSON的应⽤场景更为丰富