有使用这些库的经验的人对他们更喜欢哪一个有什么评论吗?使用过程中是否存在性能差异或困难?

有帮助吗?

解决方案

我周围一点点打了两个系统,没什么大碍,只是一些简单的hackish东西,但我觉得有一个在你应该如何使用图书馆真正发挥作用。

使用的boost ::系列化,你写你自己的结构/类第一,然后添加归档方法,但你还是留下了一些相当“苗条”类,即可以作为数据成员,继承,无论

使用协议缓冲区,因为即使一个简单的结构生成的代码量是相当可观的,而这产生的结构和代码更意味着上操作,并且使用的协议缓冲区的功能,以数据传送到和传送您的自己的内部结构。

其他提示

我一直在使用升压序列化很长一段时间,只是挖成协议缓冲区,我认为他们没有完全相同的目的。 BS(没有看到未来)保存您的C ++对象到流,而PB是你读/从交换格式。

PB的数据模型是简单的方式:你获得各种整型和浮点型,字符串,数组,基本结构,这就是这么多了。 BS可以让你直接保存你所有的物体在一个步骤。

这意味着BS你上线更多的数据,但您不必重建所有对象的结构,而协议缓冲区是更紧凑,但有读取存档后需要做更多的工作。正如其名称所表示,一个是用于协议(语言无关,空间高效的数据传递),另一种是用于序列化(没有脑子对象保存)。

那么,什么是对你更重要?速度/空间效率或干净的代码

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

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

区分不同版本很重要 你的班 (正如其他答案中提到的,boost.serialization对数据版本控制有一些支持)以及不同版本之间的兼容性 序列化库.

新版本的 boost.serialization 可能不会生成旧版本可以反序列化的档案. (反之则不然:新版本始终旨在反序列化旧版本制作的档案)。这给我们带来了以下问题:

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

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

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

脚注:无耻的插头 相关答案 由我。

增强序列化

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

协议缓冲区

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

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

编辑:10-11-24:添加“自动”到 BS 版本控制。

我没有 boost 序列化的经验,但我使用过协议缓冲区。我非常喜欢协议缓冲区。请记住以下几点(我这样说 没有知识 的提升)。

  • 协议缓冲区非常高效,所以我不 想象 这是一个严重的问题促进。
  • 协议缓冲区提供了与其他语言(Python 和 Java...以及更多作品正在进行中)。如果您知道自己只使用 C++,也许 boost 更好,但使用其他语言的选项也不错。
  • 协议缓冲区更像是数据容器......不存在面向对象的本质,例如继承。考虑一下您想要序列化的内容的结构。
  • 协议缓冲区非常灵活,因为您可以添加“可选”字段。这基本上意味着您可以在不破坏兼容性的情况下更改协议缓冲区的结构。

希望这可以帮助。

boost.serialization只需要C ++编译器和给你一些语法糖等

serialize_obj >> archive;
// ...
unserialize_obj << archive;

用于保存和加载。如果C ++是唯一的语言,你使用你应该给boost.serialization严重的射门。

我把在谷歌协议缓冲区快速外观。从我看到我会说其不具有直接可比性boost.serialization。你必须为.proto文件添加一个编译器工具链和维护.proto文件本身。该API不整合到C ++作为boost.serialization一样。

boost.serialization做这项工作其设计用于非常好:序列化C ++对象:) OTOH如谷歌协议缓冲区的查询API已经给你更多的灵活性。

由于我只用boost.serialization到目前为止我不能性能比较评价。

校正上述(猜测这是该回答 )约升压序列化:

它允许支承数据版本

如果您需要压缩 - 使用的压缩流

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

我使用boost的图书馆从来没有实现过什么,但我发现谷歌protobuff的更深思熟虑的,而且代码更清洁,更易于阅读。我建议在看看要与使用它,必须通过代码和阅读文档,让你的心的各种语言。

在一个困难我与protobufs是他们在生成的代码的GetMessage名为非常常用的功能(),它使用Win32的GetMessage宏当然冲突。

我仍然强烈建议protobufs。他们是非常有用的。

与几乎所有的工程,我的答案是......“这要看情况。”

两者都很好的测试,审核技术。双方将采取你的数据,并把它弄成友好发送某个地方。双方将可能是速度不够快,如果你真的在这里或那里计数字节,你可能不会感到高兴是(让我们面对它都创建数据包将XML或JSON的一小部分)。

对于我来说,这真的可以归结为工作流程以及是否不需要在另一端不是C ++的东西。

如果您想先弄清楚你的邮件内容和你从头开始构建系统,使用协议缓冲区。您可以在抽象的思维方式的信息,然后自动生成你想要的任何语言的代码(第三方插件可供只是一切)。另外,我发现协议缓存,简化协作。我刚刚送过来一个.proto文件,然后其他球队拥有的数据被转移什么清晰的概念。我也不强加给他们任何东西。如果他们想使用Java,勇往直前!

如果我已经以C ++类(或发生了这种情况往往不是),我想现在送过来的线数据,提振序列化明显,使一吨的感觉(特别是在我已经有一个升压依赖其他地方)。

您可以使用升压序列化与你的“真实”的域对象紧密结合,并序列完整的对象层次结构(继承)。 protobuf的不支持继承,所以你将不得不使用的聚集。人们认为的Protobuf应该用于的DTO(数据传输对象),而不是为核心域对象本身。我都用了升压::序列化和protobuf的。升压::系列化的性能应该考虑到,谷物可能是一个选择。

我知道这是一个老问题了,但我想我应该投入 2 便士!

通过 boost,你有机会在你的类中编写一些数据验证;这很好,因为数据定义和有效性检查都在一个地方。

使用 GPB,您能做的最好的事情就是在 .proto 文件中添加注释,并希望使用它的人能够阅读它、关注它并自行实施有效性检查。

不用说,如果您依赖网络流另一端的其他人以与自己相同的活力来完成此操作,那么这是不可能且不可靠的。另外,如果有效性约束发生变化,则需要计划、协调和完成多个代码更改。

因此,我认为 GPB 不适合几乎没有机会与所有团队成员定期会面和交谈的开发。

==编辑==

我的意思是这样的:

message Foo
{
    int32 bearing = 1;
}

现在谁能说出有效范围是多少 bearing 是?我们可以有

message Foo
{
    int32 bearing = 1;  // Valid between 0 and 359
}

但这取决于其他人阅读本文并为其编写代码。例如,如果您编辑它并且约束变为:

message Foo
{
    int32 bearing = 1;  // Valid between -180 and +180
}

您完全依赖于每个使用此 .proto 更新其代码的人。这是不可靠且昂贵的。

至少通过 Boost 序列化,您可以分发单个 C++ 类,并且可以直接在其中内置数据有效性检查。如果这些约束发生变化,那么除了确保他们使用与您相同版本的源代码之外,其他人不需要做任何工作。

选择

还有一个替代方案:ASN.1。这是古老的,但有一些非常非常方便的东西:

Foo ::= SEQUENCE
{
   bearing INTEGER (0..359)
}

注意约束。因此,每当有人使用这个 .asn 文件并生成代码时,他们最终都会得到会自动检查的代码 bearing 介于 0 到 359 之间。如果您更新 .asn 文件,

Foo ::= SEQUENCE
{
   bearing INTEGER (-180..180)
}

他们所需要做的就是重新编译。无需更改其他代码。

您还可以这样做:

bearingMin INTEGER ::= 0
bearingMax INTEGER ::= 360

Foo ::= SEQUENCE
{
   bearing INTEGER (bearingMin..<bearingMax)
}

请注意 <. 。而且在大多数工具中,bearingMin 和bearingMax 可以在生成的代码中显示为常量。这非常有用。

约束可以非常复杂:

Garr ::= INTEGER (0..10 | 25..32)

看看这个第13章 PDF;你能做的事情真是令人惊奇;

数组也可以被约束:

Bar ::= SEQUENCE (SIZE(1..5)) OF Foo
Sna ::= SEQUENCE (SIZE(5)) OF Foo
Fee ::= SEQUENCE 
{
    boo SEQUENCE (SIZE(1..<6)) OF INTEGER (-180<..<180)
}

ASN.1 是老式的,但仍在积极开发、广泛使用(您的手机经常使用它),并且比大多数其他序列化技术灵活得多。我发现的唯一缺陷是 Python 没有合适的代码生成器。如果您使用 C/C++、C#、Java、ADA,那么免费(C/C++、ADA)和商业(C/C++、C#、JAVA)工具的组合将为您提供良好的服务。

我特别喜欢基于二进制和文本的线格式的广泛选择。这使得它在某些项目中非常方便。线格式列表当前包括:

  • 误码率(二进制)
  • PER(二进制、对齐和未对齐。这是非常高效的。例如,INTEGER 约束在 015 将仅占用 4 bits 在电线上)
  • 开放教育资源
  • DER(另一个二进制文件)
  • XML(也称为 XER)
  • JSON(全新,工具支持仍在开发中)

加上其他人。

注意最后两个吗?是的,您可以在 ASN.1 中定义数据结构、生成代码以及以 XML 和 JSON 格式发出/使用消息。对于一项 20 世纪 80 年代兴起的技术来说,这已经相当不错了。

版本控制的方式与 GPB 不同。您可以允许扩展:

Foo ::= SEQUENCE
{
   bearing INTEGER (-180..180),
   ...
}

这意味着稍后我可以添加到 Foo, ,并且具有此版本的旧系统仍然可以工作(但只能访问 bearing 场地)。

我对 ASN.1 的评价非常高。处理起来可能很痛苦(工具可能要花钱,生成的代码不一定漂亮,等等)。但这些限制确实是一个非常棒的功能,它一次又一次地让我省去了很多心痛。当编码器/解码器报告他们生成了无效数据时,开发人员会非常抱怨。

其他链接:

观察结果

共享数据:

  • 代码优先方法(例如Boost 序列化)将您限制为原始语言(例如C++),或者强迫你用另一种语言做很多额外的工作
  • 模式优先更好,但是
    • 其中许多在共享合同中留下了很大的空白(即没有限制)。GPB 在这方面很烦人,因为它在其他方面都非常好。
    • 有些有限制(例如XSD、JSON),但工具支持不完整。
    • 例如,微软的xsd.exe主动忽略xsd文件中的约束(微软的借口确实站不住脚)。XSD 很好(从约束的角度来看),但如果您不能相信其他人会使用良好的 XSD 工具来为他/她强制实施这些约束,那么 XSD 的价值就会减弱
    • JSON 验证器没问题,但它们首先不会帮助您形成 JSON,并且不会自动调用。无法保证向您发送 JSON 消息的人已通过验证器运行它。您必须记住自己验证它。
    • ASN.1 工具似乎都实现了约束检查。

所以对我来说,ASN.1 可以做到这一点。它是最不可能导致其他人犯错误的一种,因为它具有正确的功能,并且所有工具似乎都致力于完全实现这些功能,并且对于大多数用途来说,它是语言中立的。

说实话,如果GPB加一个约束机制那就是赢家了。XSD 很接近,但工具几乎都是垃圾。如果有其他语言的不错的代码生成器,JSON 模式会非常好。

如果 GPB 添加了约束(注意:这不会改变任何有线格式),这将是我向每个人推荐用于几乎所有目的的格式。尽管 ASN.1 的 uPER 对于无线电链路非常有用。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top