【问题标题】:Java serialization alternative with better performance [closed]具有更好性能的 Java 序列化替代方案 [关闭]
【发布时间】:2012-12-23 13:49:26
【问题描述】:

假设我使用标准的 Java 对象序列化向内存缓冲区写入/读取小的 (

对于这种情况,有没有比标准 Java 序列化更快的替代方法?

【问题讨论】:

  • 为什么不试试协议缓冲区之类的东西呢?在大多数情况下,它比本机 Java 序列化更快,因为我想使用它。我开始将它用于非常简单的用例,但它慢慢成长为我参与的项目的主要部分,主要用于创建合同。
  • 我偶然发现了这个问题,因为被问到同样的问题。如果有要比较的指标(我确定有人做过这样的事情)——那么这个问题可以用事实来回答,而不是用意见来回答。它不是问题的问题——而是答案的问题。如果我错了,请纠正我 - 否则我将编辑问题,使其符合重新打开它的标准。

标签: java performance serialization


【解决方案1】:

您可能还想看看FST

还提供堆外读/写工具

【讨论】:

  • 真的很喜欢 FST。谢谢!
  • 哇,对于我的用例,我只是将我的大对象的反序列化时间从 30 多秒减少到 4 秒(另外,作为奖励,序列化形式更小),只需使用它们的 @ 987654322@。如果您在项目中依赖 JDK 序列化,这个库绝对是必须尝试的!
【解决方案2】:

看看kryo。 它比内置的序列化机制(写出大量字符串并严重依赖反射)快得多,但使用起来有点困难。
编辑:下面的 R.Moeller 建议 FST,直到现在我才听说过,但它看起来比 kryo 更快并且与 java 内置序列化兼容(这应该使它更容易使用),所以我看看第一个

【讨论】:

  • 谢谢。你知道为什么 kryo 更快吗?他们有什么不同?
  • java 内置的序列化机制在每个序列化实例的开头写下完全限定的类名 - 否则在反序列化时它不会知道它在看什么。 kryo 可以(可选地) register() 已知类(如果您事先知道您将要读取/写入的类型)并且可以使用小的 int 标头而不是 FQCN - 所以尺寸更小。您还可以为类注册序列化程序,避免反射查找(可序列化接口、序列化注释等) - 更快的 io. kryo 不处理对象版本(默认情况下,与 serialVersionUID 相比) - 再次更快。
  • 另外,当反序列化内置机制时,需要使用 FQCN 调用 Class.forName() - 比注册处理程序的映射慢。
【解决方案3】:

试试Google protobufThrift

【讨论】:

  • Protobuf 本身并不是一个序列化程序。它是一种用于创建 protobuf 类对象的消息格式。为了创建这些对象,它使用默认运行的语言的 SerDes,例如如果您使用 C++,那么它默认使用 C++ SerDes。如果您使用 java,那么在后端它使用 Java SerDes 来创建这些消息。另一方面,Kryo 是一个 SerDes,速度非常快。通常在 spark 中用作 SerDes,有时用于创建 proto/avro 类型的对象。
【解决方案4】:

标准序列化添加了很多类型信息,然后在反序列化对象时对其进行验证。当您知道要反序列化的对象的类型时,通常不需要这样做。

你可以做的是为每个类创建你自己的序列化方法,它只是将对象的所有值写入字节缓冲区,以及一个构造函数(或工厂方法,当你以这种方式摆动时)字节缓冲区并从中读取所有变量。

但就像 AlexR 一样,我想知道你是否真的需要它。序列化通常只在数据离开程序时才需要(例如存储在磁盘上或通过网络发送到另一个程序)。

【讨论】:

  • 例如,序列化的对象仍将包含完全限定的类名字符串,并且序列化仍将(相对)慢,因为它必须检查并查看您是 Serializable,甚至是 Externalizable你建议的情况
  • 我并不是建议重写标准的序列化方法 - 我是建议创建一个不使用标准的全新序列化机制。
  • 哦,那么对不起。在那种情况下,我不得不说轮子已经被发明了(kryo,等等)
【解决方案5】:

众所周知,Java 的标准序列化速度很慢,并且在磁盘上使用大量字节。进行自己的自定义序列化非常简单。
javas std 序列化非常适合演示项目,但由于上述原因不太适合专业项目。进一步的版本控制不在您的控制之下。

java 提供了自定义序列化所需的一切,请参阅我的帖子中的演示代码

Java partial (de)serialization of objects

使用这种方法,您甚至可以指定二进制文件格式,以便在 C 或 C# 中也可以读取它。 另一个优点自定义设置对象需要的空间比主内存少(布尔值在主内存中需要 4 个字节,但自定义序列化时只需要 1 个字节(作为字节)

如果不同的项目合作伙伴必须读取您的序列化数据,Google 的 Protobuf 是一个替代方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-19
    • 1970-01-01
    相关资源
    最近更新 更多