【问题标题】:Partial deserialization and serialization in Java?Java中的部分反序列化和序列化?
【发布时间】:2015-08-21 18:47:25
【问题描述】:

有大量的库和方法可以在 Java 中序列化和反序列化对象。 我想做的涉及需要在处理节点之间来回发送的相当大而复杂的对象。

然而,每个节点只对一个或几个感兴趣,通常是整个对象的一小部分。处理节点处理该部分并创建一个新部分,该部分需要在发送之前拼接到现有的序列化对象中。

为此,有两件事非常重要:

  • 能够仅反序列化部分序列化对象(从而节省解析/反序列化时间、对象创建时间、内存...),还可以将一些新部分的序列化添加到现有序列化对象中(再次节省时间和内存)——跳过序列化版本中不需要的部分应该非常快速和高效,理想情况下应该可以在流模式下进行,而无需一次将整个序列化数据保存在内存中
  • 整体紧凑且快速的序列化和反序列化。

对于实际创建类型化对象与非类型化映射和列表的自动化程度,我非常灵活:如果一切都失败了,我将能够将整个对象表示为只有映射、数组和基本数据类型布尔、字符串和数字。

更新:忘了提及另外两个相当重要的要求:

  • 解决方案必须可以使用现有对象,即不能使用例如重新实现当前对象。不同的集合类。

  • 理想情况下,解决方案应该基于开源软件,因为我需要的软件将作为开源软件自行发布。

【问题讨论】:

  • 是否可以将复杂对象分解为多个部分并序列化各个部分?
  • 你研究过外化吗?
  • 有许多库允许您使用序列化对象来提取或更新您感兴趣的字段。Chronicle Byte/Wire、SBE、Javolution 结构。
  • @Vince Emigh:据我所知,外部化基本上解决了编译时的问题,并且对于数据的一个特定子集,但我需要能够在运行时做到这一点,并且对于同一对象的多个子集:如果我将对象发送到节点 A,我想查看对象的 part1 和 part2 并添加 partA,节点 B 可能想要访问 part3 并添加 partB1 和 partB2。

标签: java performance serialization


【解决方案1】:

听起来您正在计划一个设计,将一大堆数据发送到一个处理节点,而该节点只会读取/修改/写入其中的一小部分。但随后会将整个捆绑包发送到另一个节点。

为什么不让拥有所有数据的主机弄清楚哪个节点需要哪些数据,然后只发送这些数据?然后处理可以并行进行,而不是菊花链。并且您的总网络流量将少于发送所有内容的完整副本的每个节点:O(n*m)。

可能值得设计自己的消息格式,可能基于 JSON、二进制或其他。

【讨论】:

  • 这是不可能的,因为只有处理节点会知道它想要查看哪个部分以及要添加哪个部分。数据的实际大小并不是真正的问题,但复杂性在于:整个对象的反序列化将花费大量时间,因为可能有数百万个小嵌套部分需要解包,但其中大部分是无关紧要的到节点。
  • @Johsm:嗯。 IDK 如果你真的想继续使用标准的序列化/反序列化,除了额外的往返之外,还有什么建议:服务器告诉节点它想让节点做什么。节点请求数据集的特定部分。服务器发送它,等等等等。
  • TBH 我原以为只查看序列化对象的一部分的要求会更常见,因此存在标准解决方案。如果没有,我会接受自己做饭,但重新发明现有的轮子会很可惜。
  • @Johsm:为了使部分反序列化有效,您需要某种索引,不是吗?否则接收者仍然需要解析所有的序列化数据,而不是从中创建对象。 IDK,可能有一种方法可以使用一些标准 API 来做到这一点。我不知道怎么做,但我不是专家。我只是回答建议一个更有效的解决方案。希望这不会吓跑对序列化 API/库有更多经验的人的回答。
  • 我认为我所追求的是一种简单的方法来“跳过”不需要的对象的反序列化,或者在序列化时,将另一个对象添加到现有的复杂、已经序列化的数据结构中。例如,如果对象是一个映射,我可能只对该映射中单个键的对象感兴趣,而留下数千个其他对象(可能每个对象都非常复杂)未解析。我认为对于包含长度的许多(二进制)序列化格式,应该很容易跳过映射中不需要的条目,只反序列化我感兴趣的一个条目。
猜你喜欢
  • 2013-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-17
  • 2011-08-17
  • 2012-09-22
相关资源
最近更新 更多