Scala/Java 中的简单、无麻烦、零样板序列化类似于 Python 的 Pickle?
Scala/Java 中是否有一种类似于 Python 的 pickle 的简单、无麻烦的序列化方法? Pickle 是一个极其简单的解决方案,在空间和时间上相当有效(即不是很糟糕),但不关心跨语言可访问性、版本控制等,并允许可选的自定义。
我所知道的是:
- Java 的内置序列化速度非常慢 ([1]< /a>, [2]),臃肿、脆弱。还必须将类标记为可序列化——当有些东西明显可序列化但没有该注释时(例如,没有多少 Point2D 作者将这些标记为可序列化),这很烦人。
- Scala 的 BytePickle 需要一堆样板文件键入你想要腌制的内容,即使这样它不适用于(循环)对象图。
- jserial:未维护且似乎并没有比默认的 Java 序列化更快/更小。
- kryo:无法(反)序列化没有 0 参数的对象,这是一个严重的限制。 (此外,您还必须注册计划序列化的每个类,否则您会得到 显着减慢/膨胀,但即便如此,它仍然比 pickle 更快。)
- protostuff:AFAICT,您必须在“模式”中提前注册要序列化的每个类。
Kryo 和 protostuff 是我发现的最接近的解决方案,但我想知道是否还有其他解决方案(或者是否有某种我应该知道的使用这些解决方案的方法)。请附上使用示例!理想情况下还包括基准。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我实际上认为你最好使用 kryo (我不知道除了非二进制协议之外提供更少模式定义的替代方案)。您提到,pickle 不会受到 kryo 在不注册类的情况下出现的速度减慢和膨胀的影响,但即使没有注册类,kryo 仍然比 pickle 更快且更不臃肿。请参阅以下微基准(显然要持保留态度,但这就是我可以轻松做到的):
Python pickle
对我来说输出 174 字节和 1.18-1.23 秒(64 位 Linux 上的 Python 2.7.1)
Scala kryo
为我输出 68 个字节和 30-40 毫秒(Kryo 1.04、Scala 2.9.1、Java 64 位 Linux 上的 1.6.0.26 热点 JVM)。作为比较,如果我注册类,它会输出 51 个字节和 18-25 毫秒。
对比
Kryo 在不注册类时使用 Python pickle 约 40% 的空间和 3% 的时间,而在注册类时则使用约 30% 的空间和 2% 的时间。当您需要更多控制时,您始终可以编写自定义序列化程序。
I actually think you'd be best off with kryo (I'm not aware of alternatives that offer less schema defining other than non-binary protocols). You mention that pickle is not susceptible to the slowdowns and bloat that kryo gets without registering classes, but kryo is still faster and less bloated than pickle even without registering classes. See the following micro-benchmark (obviously take it with a grain of salt, but this is what I could do easily):
Python pickle
Outputs 174 bytes and 1.18-1.23 seconds for me (Python 2.7.1 on 64-bit Linux)
Scala kryo
Outputs 68 bytes for me and 30-40ms (Kryo 1.04, Scala 2.9.1, Java 1.6.0.26 hotspot JVM on 64-bit Linux). For comparison, it outputs 51 bytes and 18-25ms if I register the classes.
Comparison
Kryo uses about 40% of the space and 3% of the time as Python pickle when not registering classes, and about 30% of the space and 2% of the time when registering classes. And you can always write a custom serializer when you want more control.
编辑2020-02-19:请注意,正如下面@federico提到的,这个答案不再有效,因为存储库已被所有者存档。
Scala 现在有 Scala-pickling,根据场景,其性能与 Kyro 一样好或更好 - 请参阅幻灯片 34- 39 在 此演示文稿。
Edit 2020-02-19: please note, as mentioned by @federico below, this answer is no longer valid as the repository has been archived by the owner.
Scala now has Scala-pickling which performs as good or better than Kyro depending on scenario - See slides 34-39 in this presentation.
Twitter 的 chill 库 非常棒。它使用 Kryo 进行序列化,但使用起来非常简单。也很好:提供了一个 MeatLocker[X] 类型,使任何 X 都可以序列化。
Twitter's chill library is just awesome. It uses Kryo for serialization but is ultra simple to use. Also nice: provides a MeatLocker[X] type which makes any X a Serializable.
我会推荐 SBinary。它使用在编译时解析的隐式,因此非常有效且类型安全。它内置了对许多常见 Scala 数据类型的支持。您必须为您的(案例)类手动编写序列化代码,但这很容易做到。
简单 ADT 的使用示例
I would recommend SBinary. It uses implicits which are resolved at compile time, so it's very effective and typesafe. It comes with built-in support for many common Scala datatypes. You have to manually write the serialization code for your (case) classes, but it's easy to do.
A usage example for a simple ADT
另一个不错的选择是最近的(2016)
**netvl/picopickle**
:例如:
Another good option is the recent (2016)
**netvl/picopickle**
:For example: