提升序列化与谷歌协议缓冲?

0xC*_*ACE 64 c++ performance serialization protocol-buffers boost-serialization

有这些图书馆经验的人对他们喜欢哪一个有任何评论吗?使用中是否存在任何性能差异或困难?

ndf*_*red 44

我已经使用Boost Serialization很长一段时间了,只是挖掘协议缓冲区,我认为它们没有完全相同的目的.BS(没看到即将发布)将C++对象保存到流中,而PB是您可以读取/来自的交换格式.

PB的数据模型更简单:你得到各种整数和浮点数,字符串,数组,基本结构,这就是它.BS允许您一步直接保存所有对象.

这意味着使用BS可以在线路上获得更多数据,但是您不必重建所有对象结构,而协议缓冲区更紧凑,但在阅读存档后还有更多工作要做.顾名思义,一个用于协议(语言无关,空间有效的数据传递),另一个用于序列化(保存无脑的对象).

那么对您来说更重要的是:速度/空间效率还是干净的代码?


Mag*_*ind 29

我用两个系统玩了一下,没有什么严重的,只是一些简单的hackish东西,但我觉得你应该如何使用这些库有一个真正的区别.

使用boost :: serialization,你首先编写自己的结构/类,然后添加归档方法,但你仍然留下一些非常"苗条"的类,可以用作数据成员,继承,等等.

使用协议缓冲区,即使是简单的结构生成的代码量也相当大,生成的结构和代码更适合于操作,并且您使用协议缓冲区的功能来传输数据到您自己的内部结构和从您自己的内部结构传输数据.

  • 通常,您不需要在自己的内部结构中传输数据 - 您可以使用协议缓冲区直接填充这些结构.它们本质上是值类,它们具有移动语义,并且它们与STL和Boost集合很好地配合. (2认同)

bac*_*car 26

还有一些关于boost.serialization的额外问题,我将添加到混合中.警告:除了浏览文档之外,我对协议缓冲区没有任何直接经验.

请注意,虽然我认为boost和boost.serialization在它的功能方面非常出色,但我得出的结论是,它带来的默认存档格式对于有线格式来说并不是一个很好的选择.

版本之间的区别是很重要的你的类(在其他的答案中提到,boost.serialization有数据版本的一些支持)不同版本之间的兼容性和序列化库.

较新版本的boost.serialization 可能无法生成旧版本可以反序列化的存档.(反之亦然:较新版本始终用于反序列化旧版本制作的档案).这给我们带来了以下问题:

  • 我们的客户端和服务器软件都创建了另一个消耗的序列化对象,因此如果我们以锁步方式升级客户端和服务器,我们只能转向更新的boost.serialization.(在您无法完全控制客户的环境中,这是一个相当大的挑战).
  • Boost捆绑为一个带有共享部分的大型库,并且序列化代码和boost库的其他部分(例如shared_ptr)可能在同一个文件中使用,我无法升级boost的任何部分,因为我可以'升级boost.serialization.我不确定尝试将多个版本的boost链接到单个可执行文件中是否可行/安全/合理,或者我们是否有预算/能量将需要保留在较旧版本的boost上的位重构为单独的可执行文件(在我们的例子中是DLL)
  • 我们坚持使用的旧版本的boost不支持我们使用的最新版本的编译器,所以我们也停留在旧版本的编译器上.

Google似乎实际上发布了协议缓冲区有线格式,而维基百科将它们描述为向前兼容,向后兼容(尽管我认为维基百科指的是数据版本控制而不是协议缓冲库版本控制).虽然这些都不是前向兼容性的保证,但对我来说似乎是一个更强有力的指示.

总之,当我无法以锁步方式升级客户端和服务器时,我更喜欢一种众所周知的已发布的有线协议缓冲区格式.

脚注:我无耻地插上相关答案.

  • 仅供参考:2.5年后,我现在有很多关于协议缓冲的直接经验,我支持上面的评论. (8认同)

Nic*_*ick 16

提升序列化

  • 是一个用于将数据写入流的库.
  • 不压缩数据.
  • 不自动支持数据版本控制.
  • 支持STL容器.
  • 写入的数据属性取决于所选择的流(例如,字节序,压缩).

协议缓冲区

  • 从接口描述生成代码(默认支持C++,Python和Java.第三方支持C,C#和其他).
  • 可选地压缩数据.
  • 自动处理数据版本控制.
  • 处理平台之间的字节序交换.
  • 不支持STL容器.

Boost序列化是一个用于将对象转换为序列化数据流的库.Protocol Buffers做同样的事情,但也为你做其他工作(比如版本控制和endian交换).对于"小型简单任务",Boost序列化更简单.协议缓冲区可能更适合"更大的基础架构".

编辑:24-11-10:添加"自动"到BS版本.

  • 数据压缩通常通过具有增强iostream的组合来完成.它不是升级序列化的一部分,因为这样做会是多余的. (6认同)
  • boost序列化包括从一开始就对数据进行版本控制.这是默认和自动的.如果您不希望对某些数据类型进行版本控制,则可以逐个类型地禁用它.但通常这几乎从未完成. (3认同)
  • 嗯......这似乎不完全正确,因为BS有版本控制,据我所知,端点问题取决于你使用的序列化格式. (2认同)

Tom*_*Tom 14

我没有使用boost序列化的经验,但我使用了协议缓冲区.我非常喜欢协议缓冲区.记住以下内容(我说这不知道提升).

  • 协议缓冲区是非常有效的,所以我不想象这是一个严重的问题与提升.
  • 协议缓冲区提供了一个适用于其他语言的中间表示(Python和Java ......以及更多工作).如果您知道自己只使用C++,那么提升可能会更好,但使用其他语言的选项很不错.
  • 协议缓冲区更像是数据容器......没有面向对象的特性,例如继承.想想你要序列化的结构.
  • 协议缓冲区很灵活,因为您可以添加"可选"字段.这基本上意味着您可以更改协议缓冲区的结构而不会破坏兼容性.

希望这可以帮助.


Mai*_*ann 11

boost.serialization只需要C++编译器,并为你提供一些语法糖

serialize_obj >> archive;
// ...
unserialize_obj << archive;
Run Code Online (Sandbox Code Playgroud)

用于保存和加载.如果C++是你使用的唯一语言,你应该给boost.serialization一个严肃的镜头.

我快速浏览了谷歌协议缓冲区.从我看到的,我说它不能直接与boost.serialization相媲美.您必须将.proto文件的编译器添加到工具链并维护.proto文件本身.API没有像boost.serialization那样集成到C++中.

boost.serialization完成了它的设计工作:序列化C++对象:) OTOH像谷歌协议缓冲区这样的查询API为您提供了更大的灵活性.

由于到目前为止我只使用了boost.serialization,所以我无法对性能比较发表评论.


小智 7

有关Boost序列化的更正(猜测这是答案):

它允许支持数据版本控制.

如果需要压缩 - 请使用压缩流.

可以处理平台之间的字节序交换,因为编码可以是文本,二进制或XML.


i_a*_*orf 6

我从来没有使用boost的库实现任何东西,但我发现Google protobuff更加深思熟虑,而且代码更清晰,更易于阅读.我建议你看看你想要使用它的各种语言,并阅读代码和文档,并下定决心.

我使用protobufs的一个难点是他们在生成的代码GetMessage()中命名了一个非常常用的函数,当然这与Win32 GetMessage宏有冲突.

我仍然强烈推荐protobufs.它们非常有用.