提升序列化与谷歌协议缓冲区?
有这些图书馆经验的人有没有评论他们喜欢哪一个? 在使用中是否存在性能差异或困难?
我已经在这两个系统上玩了一下,没有什么严重的,只是一些简单的黑客,但是我觉得你应该如何使用这些库有一个真正的区别。
使用boost :: serialization,首先编写自己的结构体/类,然后添加归档方法,但是仍然留有一些相当“瘦”的类,可以用作数据成员,inheritance,不pipe。
使用协议缓冲区,为简单的结构生成的代码量相当大,生成的结构和代码更多地用于操作,并且使用协议缓冲区的function将数据传入或传出自己的内部结构。
我一直在使用Boost Serialization,只是深入研究协议缓冲区,我认为它们并没有完全相同的目的。 BS(没有看到)将你的C ++对象保存到一个stream中,而PB是你读/写的交换格式。
PB的数据模型比较简单:你可以获得各种数据和浮点数,string,数组,基本结构等等。 BS允许你直接保存所有的对象在一个步骤。
这意味着BS可以在线上获得更多的数据,但是不必重新构build所有的对象结构,而协议缓冲区更加紧凑,但是在阅读归档之后还有更多的工作要做。 正如名字所说,一个是用于协议(语言不可知,空间高效的数据传递),另一个用于序列化(不需要考虑的对象保存)。
那么更重要的是:速度/空间效率还是干净的代码?
boost.serialization还有一些额外的问题,我将添加到混合中。 警告:除了浏览文档之外,我没有使用协议缓冲区的直接经验。
请注意,尽pipe我认为boost和boost.serialization对于它的function非常好,但是我得出的结论是它自带的默认存档格式对于有线格式并不是一个好的select。
区分你的类的版本是很重要的(正如其他答案中提到的,boost.serialization对数据版本的支持)以及不同版本的序列化库之间的兼容性。
较新版本的boost.serialization 可能不会生成旧版本可以反序列化的存档 。 (反之则不然:新版本总是打算对旧版本的档案进行反序列化)。 这给我们带来了以下问题:
- 我们的客户端和服务器软件都会创build另一个消耗的序列化对象,所以如果我们同时升级客户端和服务器,我们只能移动到更新的boost.serialization。 (在没有完全控制客户的环境中,这是一个相当大的挑战)。
- Boost作为一个带有共享部分的大型库被捆绑在一起,并且序列化代码和boost库的其他部分(例如shared_ptr)可能在同一个文件中使用,我不能升级boost的任何部分,因为我可以'升级boost.serialization。 我不确定是否有可能/安全/理智地尝试将多个版本的boost升级到单个可执行文件,或者如果我们有足够的预算/能量来重构那些需要保留在旧版本的boost中的位可执行文件(我们的例子中的DLL)。
- 我们坚持使用的旧版本的boost不支持我们使用的最新版本的编译器,所以我们也停留在旧版本的编译器上。
谷歌似乎实际上发布了协议缓冲区连线格式 ,维基百科将它们描述为向前兼容,向后兼容 (尽pipe我认为维基百科是指数据版本控制而不是协议缓冲库版本控制)。 虽然这两者都不是前锋兼容的保证,但对我来说,这似乎更有说服力。
总之,当我没有能力以锁步方式升级客户端和服务器时, 我更喜欢一个众所周知的,发布的协议缓冲区的线路格式 。
脚注:无耻插我的相关答案 。
提升序列化
- 是将数据写入stream的库。
- 不压缩数据。
- 不支持数据版本自动。
- 支持STL容器。
- 写入数据的属性取决于所select的stream(例如,endian,压缩)。
协议缓冲区
- 从接口描述中生成代码(默认支持C ++,Python和Java,C,C#和其他第三方)。
- 可选地压缩数据。
- 自动处理数据版本。
- 处理平台之间的endian交换。
- 不支持STL容器。
Boost序列化是一个将对象转换为序列化的数据stream的库。 协议缓冲区做同样的事情,但也为你做其他工作(如版本控制和端到端交换)。 Boost序列化对于“小型简单任务”更简单。 协议缓冲区可能更适合“大型基础设施”。
编辑:24-11-10:“自动”添加到BS版本。
我没有使用boost序列化的经验,但是我使用了协议缓冲区。 我喜欢协议缓冲区。 请记住以下内容(我没有提高知识而这样说)。
- 协议缓冲区是非常有效的,所以我不认为这是一个严重的问题与提振。
- 协议缓冲区提供了一种与其他语言(Python和Java等等)协同工作的中间表示forms。 如果你知道你只使用C ++,也许提升更好,但使用其他语言的选项是好的。
- 协议缓冲区更像数据容器……没有面向对象的本质,如inheritance。 考虑你想要序列化的结构。
- 协议缓冲区是灵活的,因为您可以添加“可选”字段。 这基本上意味着您可以更改协议缓冲区的结构而不会破坏兼容性。
希望这可以帮助。
boost.serialization只需要C ++编译器,并给你一些语法糖
serialize_obj >> archive; // ... unserialize_obj << archive;
用于保存和加载。 如果C ++是你使用的唯一的语言,你应该给boost.serialization一个严重的问题。
我快速浏览了google协议缓冲区。 从我看来我会说它不能直接比较boost.serialization。 您必须将.proto文件的编译器添加到您的工具链,并维护.proto文件本身。 API并没有像boost.serialization那样集成到C ++中。
boost.serialization做它的devise很好的工作:序列化C ++对象OTOH查询API像谷歌协议缓冲区给你更多的灵活性。
由于我只使用boost.serialization到目前为止我不能评论性能比较。
更正以上(猜测这是答案 )有关升压序列化:
它允许支持数据版本 。
如果你需要压缩 – 使用压缩的stream。
可以处理平台之间的交换,因为编码可以是文本,二进制或XML。
我从来没有使用boost的库来实现任何东西,但是我发现Google protobuff是更加深思熟虑的,而且代码更清晰,更易于阅读。 我会build议看看你想使用它的各种语言,并阅读代码和文档,并下定决心。
我用protobufs遇到的一个难题是在生成的代码GetMessage()中命名了一个非常常用的函数,这当然与Win32的GetMessagemacros冲突。
我仍然强烈推荐protobufs。 他们非常有用。
就像几乎所有的工程一样,我的答案是……“这取决于”。
两者都经过良好的testing,审查技术。 两者都将把你的数据,并把它变成友好的发送到某个地方。 两者都可能足够快,如果你真的在这里或那里计算一个字节,你可能不会满意(让我们面对它创build的数据包将只是XML或JSON的一小部分)。
对我来说,这真的归结为工作stream程,不pipe你是否需要C ++以外的东西。
如果你想先弄清楚你的消息内容,并且从头开始构build一个系统,那么使用Protocol Buffers。 你可以用抽象的方式来思考这个消息,然后用你想要的任何语言自动生成代码(第三方插件几乎可用)。 另外,我发现Protocol Buffers简化了协作。 我只是发送一个.proto文件,然后另一个团队就清楚地知道要传输什么数据。 我也不强加任何东西。 如果他们想使用Java,请继续!
如果我已经用C ++构build了一个类(而且这种情况经常发生),我现在想通过线路发送这些数据,但是Boost Serialization显然有很大的意义(特别是在其他地方我已经拥有Boost依赖的情况下) )。