C++ 序列化性能

Posted

技术标签:

【中文标题】C++ 序列化性能【英文标题】:C++ Serialization Performance 【发布时间】:2010-09-24 05:04:25 【问题描述】:

我正在构建一个分布式 C++ 应用程序,该应用程序需要对在不同进程和计算机之间传递的简单数据结构进行大量序列化和反序列化。

我对序列化复杂的类层次结构不感兴趣,但更多的是发送带有一些简单成员(如数字、字符串和数据向量)的结构。数据向量通常可以是许多兆字节。 我担心基于 text/xml 的方法太慢了,我真的不想自己写这个,因为字符串编码和数字字节序等问题会使它比表面上看起来更复杂。

我一直在研究协议缓冲区和 boost.serialize。根据文档,协议缓冲区似乎非常关心性能。 从某种意义上说,Boost 似乎更轻量级,因为您没有用于指定数据格式的外部语言,我觉得这对于这个特定项目非常方便。

所以我的问题归结为:有人知道对于我上面描述的典型用例,boost 序列化是否很快?

此外,如果还有其他可能适合此的库,我很乐意听到它们。

【问题讨论】:

【参考方案1】:

我强烈建议使用协议缓冲区。它们使用起来非常简单,提供出色的性能,并解决了字节顺序和向后兼容性等问题。为了使其更具吸引力,由于多种语言实现,序列化数据与语言无关。

【讨论】:

【参考方案2】:

您会想到 ACE 和 ACE TAO,但您可能不喜欢它的大小和范围。 http://www.cs.wustl.edu/~schmidt/ACE.html

关于您对“快速”和提升的查询。这是一个主观术语,在不知道您的要求(吞吐量等)的情况下,很难为您回答这个问题。并不是说我自己对提升的东西有任何基准......

您可以使用一些消息传递层,但它们可能比 boost 慢。我想说你在 boost 中找到了一个很好的解决方案,但我只使用了 ACE 和其他专有的通信/消息传递产品。

【讨论】:

【参考方案3】:

我的猜测是 boost 足够快。我在之前的项目中使用它来将数据序列化到磁盘和从磁盘中读取数据,它的性能甚至从未成为问题。

我的answer 在这里谈论一般的序列化,除了选择使用哪个序列化库之外,这可能对您有所帮助。

话虽如此,您似乎知道序列化(字节序字符串编码)的大部分主要问题。您确实忽略了版本控制和向前/向后兼容性。如果时间不重要,我建议您编写自己的序列化代码。这是一次启发性的经历,你学到的教训是无价的。虽然我会警告你,但它会让你讨厌基于 XML 的协议的臃肿。 :)

无论你选择哪条路,祝你的项目好运。

【讨论】:

【参考方案4】:

也可以查看ONC-RPC (old SUN-RPC)

【讨论】:

我们已经使用 sun rpc 成功地完成了 15 年。它生成的 C++ 代码使用简单,适用于我尝试过的所有操作系统。【参考方案5】:

boost.serialization 不关心字符串编码或字节顺序。如果这对您很重要,您也可以不使用它。

您可能想从 ZeroC 研究 ICE:http://www.zeroc.com/

它的工作方式与 CORBA 类似,只是它完全由公司指定和定义。好处是实现按预期工作,因为没有那么多。不利的一面是,如果您使用的是他们不支持的语言,那么您就不走运了。

【讨论】:

请注意许可条款:开源项目是免费的,但对于商业应用程序来说非常昂贵(无论如何,大多数商业 CORBA ORB)。 是的,它对于商业应用来说很昂贵。如果您考虑到使用 CORBA 或 SOAP 方法(将 ORB 与对规范的不同解释混合)总是会遇到的麻烦,IMO 的价格相当不错:) 关于 boost 不支持字节序的好点。我认为提升序列化索引页面上的数据可移植性目标暗示它实际上是受支持的。但是,该项目的待办事项列表中也提到了这一点:) 据我所知,boost 序列化是可移植的,只要您不使用二进制序列化技术。显然 text 和 xml 都会产生可移植的数据。但是,如果您注意到磁盘空间成为一个问题,您可能需要重新考虑。我认为正在开发一种可移植的二进制格式【参考方案6】:

如果您只发送定义明确的数据结构,那么也许您应该将ASN.1 视为一种编码方法?

【讨论】:

【参考方案7】:

还有Thrift,它看起来像一个alpha项目,但由Facebook使用和开发,所以它的用户很少。

或者旧的 DCE,这是 MS 决定用于 COM 的标准。它现在是开源的,虽然晚了 20 年,但总比没有好。

【讨论】:

Thrift 也被 Evernote API blog.evernote.com/tech/2011/05/26/evernote-and-thrift使用【参考方案8】:

不要抢先优化。先测量再优化。

【讨论】:

我认为这种方法对于容易被替换的东西是有好处的。外部库可能并不难改变,但我绝对认为如果我能看到问题出现,在做出决定之前做一些功课是值得的。

以上是关于C++ 序列化性能的主要内容,如果未能解决你的问题,请参考以下文章

最便捷最强大速度最快的C++序列化框架

Swifter.Json 可能是 .Net 平台迄今为止性能最佳的 Json 序列化库开源

Swifter.Json 可能是 .Net 平台迄今为止性能最佳的 Json 序列化库开源

Golang 序列化之 ProtoBuf

反转整数序列

谷物和 Boost 序列化是不是使用零拷贝?