当前位置: 首页 > 面试题库 >

高性能序列化:Java vs Google协议缓冲区vs…?

终子昂
2023-03-14
问题内容

对于某些缓存,我正在考虑为即将到来的项目做准备,我一直在考虑Java序列化。即,应该使用它吗?

现在,由于几年来的各种原因,我以前已经编写了自定义序列化和反序列化(可外部化)。如今,互操作性已成为一个更大的问题,并且我可以预见需要与.Net应用程序进行交互,因此我考虑使用独立于平台的解决方案。

有没有人对GPB的高性能使用有任何经验?与Java的本机序列化相比,它在速度和效率方面有何不同?另外,还有其他值得考虑的方案吗?


问题答案:

我没有将协议缓冲区与Java的本机序列化在速度方面进行比较,但是对于互操作性,Java的本机序列化是一个严重的禁忌。在大多数情况下,它在空间方面也不会像协议缓冲区那样高效。当然,它可以存储的内容以及引用等方面都更加灵活。协议缓冲区非常适合它的预期用途,并且在满足您的需求时非常有用-
但由于互操作性,存在明显的限制(和其他东西)。

我最近在Java和.NET中发布了协议缓冲区基准测试框架。Java版本在Google主项目中(位于基准目录中),.
NET版本在我的C#端口项目中。如果要将PB速度与Java序列化速度进行比较,则可以编写类似的类并对它们进行基准测试。如果您对互操作感兴趣,那么我真的不会再考虑本机Java序列化(或.NET本机二进制序列化)。

除了协议缓冲区,还有其他一些可互操作的序列化选项-Thrift,JSON和YAML浮现在脑海,毫无疑问还有其他选择。

编辑:好的,互操作性不是那么重要,值得尝试从序列化框架中列出您想要的不同质量。您应该考虑的一件事就是版本控制-
这是PB设计成可以很好地处理的事情,无论是向前还是向后(这样,新软件就可以读取旧数据,反之亦然)-当您遵循建议的规则时,当然:)

在尝试对Java性能与本机序列化保持谨慎的同时,发现PB的速度反而让我真的感到惊讶。如果有机会,请使用服务器虚拟机-
我最近的基准测试表明,服务器虚拟机在序列化和反序列化示例数据方面的 速度其两倍 。我认为PB代码非常适合服务器VM的JIT :)

就像样本性能数据一样,我将使用服务器VM在笔记本电脑上获得了以下结果,即序列化和反序列化了两条消息(一个228字节,一个84750字节):

使用google_message1.dat文件进行基准化基准测试。GoogleSize$ SizeMessage1 
序列化为字节字符串:30.16秒内进行2581851次迭代;18.613789MB /秒
序列化为字节数组:29.842s中的2583547次迭代;18.824497MB /秒
序列化到内存流:30.125秒内进行2210320次迭代;15.953759MB /秒
从字节字符串反序列化:在30.088s中进行了3356517次迭代;24.256632MB /秒
从字节数组反序列化:29.958s中的3356517次迭代;24.361889MB /秒
从内存流中反序列化:29.821s中的2618821迭代;19.094952MB /秒

使用文件google_message1.dat进行基准化基准测试。GoogleSpeed$ SpeedMessage1 
序列化为字节字符串:29.978 s中进行了17068518次迭代;123.802124MB /秒
序列化为字节数组:在30.043秒内迭代17520066;126.802376MB /秒
序列化到内存流:30.076s中的7736665次迭代;55.93307MB /秒
从字节字符串反序列化:在30.073s中进行16123669次迭代;116.57947MB /秒
从字节数组反序列化:在30.109秒内迭代16082453;116.14243MB /秒
从内存流中反序列化:在30.03秒内进行7496968次迭代;54.283176MB /秒

使用文件google_message2.dat进行基准化基准测试。GoogleSize$ SizeMessage2 
序列化为字节字符串:30.034秒内进行6266次迭代;16.826494MB /秒
序列化为字节数组:在30.027秒内进行6246次迭代;16.776697MB /秒
序列化到内存流:29.916s中的6042次迭代;16.288969MB /秒
从字节字符串反序列化:29.819s中的4675次迭代;12.644595MB /秒
从字节数组反序列化:在30.093s中进行4694次迭代;12.580387MB /秒
从内存流中反序列化:在29.579s内进行了4544次迭代;12.389998MB /秒

使用文件google_message2.dat进行基准化基准测试。GoogleSpeed$ SpeedMessage2 
序列化为字节字符串:30.055秒内执行39562次迭代;106.16416MB /秒
序列化为字节数组:30.178秒内进行39715次迭代;106.14035MB /秒
序列化到内存流:30.032s中的34161次迭代;91.74085MB /秒
从字节字符串反序列化:29.794 s中的36934次迭代;99.98019MB /秒
从字节数组反序列化:在29.915s中进行了37191次迭代;100.26867MB /秒
从内存流中反序列化:29.846 s中的36237次迭代;97.92251MB /秒

“速度”与“大小”是所生成的代码是否针对速度或代码大小进行了优化。(在两种情况下,序列化的数据都是相同的。“
size”版本是为以下情况提供的:您已定义了许多消息,并且不想为代码占用大量内存。)

如您所见,对于较小的消息,它可以 非常 快- 每毫秒 对500条以上的小消息进行序列化或反序列化。即使使用87K消息,每条消息花费的时间也不到毫秒。



 类似资料:
  • 这就是我想要实现的: > 在Proc#1中使用google协议缓冲区建模对象 使用proto-buf序列化该对象,并将其发送到posix消息队列。 在Proc#2中读取流并将其反序列化为类似的模型,同时使用协议缓冲区。 换句话说: 进程1中的对象-- 问题是Proc#1和Proc#2可能是完全不同的语言平台。程序#1通常是C与g相一致的。但是Proc#2可以是任何东西:Python、Java等等。

  • 我有kafka集群接收消息。消息是一个字节数组的zip文件。zip文件包含二进制的原型数据文件作为条目。我正在读取zip文件,并试图反序列化的原型条目,这就是我的代码是打异常。 在将二进制protobuf文件作为压缩字节数组发送到代理之前,我能够对其进行反序列化。 但是,当我压缩这些二进制protobuf文件,向kafka生成消息,使用它,然后尝试反序列化zip流中的条目时,我面临着一些问题。 我

  • 是否有可能在C中序列化一个类,并使用协议缓冲区将其反序列化为C#中的类似类?我已经尝试过Json序列化来克服不同平台中的序列化问题,但它在一些数据类型上存在问题,如数组列表等。那么关于使用谷歌协议缓冲区有什么建议吗?

  • 我们接近100人。proto文件,其中每个文件可以定义大约10个IDL结构(如服务或消息)。 有没有一种方法可以可视化它们,包括引用(从一个文件到另一个文件)。例如类似于UML类图。 可能有可配置的可视化Java /C。 引用自https://developers.google.com/protocol-buffers/docs/overview 协议缓冲区现在是谷歌的通用数据语言——在撰写本文时

  • 默认情况下,Dart-RPC在服务器和客户端之间传输对象(类实例)时使用JSON序列化。 如何使用Protobuf(协议缓冲区)序列化 是否可以使用“接受”请求标头指定序列化方法(如内容类型)? 这是我尝试的, 我使用了以下定义文件,表示实体: 生成了人。pb。dart对于我来说,使用protoc gen dart插件,通过运行以下命令: 还有一些样板dart rpc代码: 打开功能请求:http

  • 问题内容: 我们正在研究传输/协议解决方案,并且即将进行各种性能测试,因此我认为我应该与社区联系,以了解他们是否已经这样做: 有没有人比较Linux上的EJB3,Thrift和协议缓冲区,对简单的回显服务进行了服务器性能测试,并对各种消息大小进行了序列化/反序列化? 主要的语言是Java,C / C ++,Python和PHP。 更新:我仍然对此很感兴趣,如果有人做了进一步的基准测试,请告诉我。另