java - MicroStream(反序列化)如何工作?

标签 java serialization deserialization microstream

我想知道MicroStream的序列化如何工作。
由于它被描述为“超快”,因此必须依靠代码生成,对吗?还是基于反思?
与Protobuf-Serialization相比,它的性能如何?Protobuf-Serialization依赖于直接从java字段中读取并将其写入字节缓冲区的Code-generation,反之亦然。
在大范围串行化对象时,使用反射会大大降低性能,不是吗?

我正在寻找一种快速的方法来为多人游戏传输和持久存储对象,并且每一毫秒都很重要。 :)

提前致谢!

PS:由于我的信誉不高,因此无法创建“微流”标签。 https://microstream.one/

最佳答案

我是MicroStream的首席开发人员。
(这不是别名帐户。我确实是创建它的。我在StackOverflow上阅读了10年左右,但从未有过创建帐户的理由。直到现在。)

在每次初始化时,MicroStream都会分析所有必需实体和值类型类的当前运行时版本,并从中获取优化的元数据。
在运行时遇到迄今为止尚不了解的类时,将执行相同的操作。
分析是针对每个反射进行的,但是由于对于每个处理的类仅进行一次分析,因此反射性能成本可以忽略不计。
实际的存储和加载或序列化和反序列化是基于创建的元数据通过优化的框架代码完成的。

如果类布局发生更改,则类型分析将从存储该类实例的字段布局创建映射到当前类的映射。
如有可能,自动进行(明确的更改或通过一些可配置的试探法),否则通过用户提供的映射。性能保持不变,因为JVM不在乎它(简而言之)是否将加载的值3复制到位置3或位置5。全部在元数据中。

使用了ByteBuffer,更精确地说是直接使用ByteBuffer,但仅用作通过直接“不安全”低级操作来处理堆外内存的锚点。如果您不熟悉“不安全”操作,那么一个简短而简单的概念就是:“它与C ++代码一样直接和快速。”您可以非常快地完成几乎所有需要的操作,但是您也要对所有事情负责。有关更多详细信息,请谷歌“ sun.misc.Unsafe”。

没有代码生成。没有使用字节码黑客攻击,通过代理或类似的猴子业务默认替换实例。从技术上讲,它只是一个Java库(包括“不安全”用法),但具有许多经过适当设计的逻辑。

附带说明:反射速度不像通常认为的那样慢。不再。确实如此,但是在过去的Java版本中已经对其进行了很多优化。
只有每项操作都必须重新进行所有的类分析,字段查找等操作时,它才很慢(很多框架似乎都做得不好,因为它们写得不好)。如果一次收集(设置可访问性等)字段然后将其缓存,则反射实际上出奇地快。

关于与Protobuf序列化的比较:

由于我没有使用过协议缓冲区,而且我不知道它在内部如何工作,因此我无法透露任何具体信息。
与复杂技术一样,由于不同的技术具有不同的优化优先级和限制,因此很难进行真正有意义的比较。

大多数序列化方法都放弃了引用一致性,但只存储“数据”(即,如果两个对象引用了第三个对象,则反序列化将创建该第三个对象的两个实例。
这样:A-> C <-B ==序列化==> A-> C1 B-> C2。
基本上,这会破坏/破坏/破坏对象图,并使循环图的序列化成为不可能,因为它会创建并无限级联复制。例如,请参阅JSON序列化。有趣的事。)
甚至Brian Goetz的Java“ Serialization 2.0”草案也包含该限制(请参阅http://cr.openjdk.java.net/~briangoetz/amber/serialization.html的“限制”)(以及另一个打破关注点分离的限制)。

MicroStream没有该限制。它可以正确处理任意对象图,而不会破坏它们的引用。
他写道,到目前为止,保持参照一致性不变并不是“尝试做太多事情”。这是“做得正确”。一个人只需要知道如何正确地做。如果正确完成,它甚至是微不足道的。
因此,根据Protobuf-Serialization的局限性(“恶魔般的脚步”),它可能几乎无法甚至根本无法与MicroStream相提并论。

当然,您始终可以针对自己的特定需求创建一些性能比较测试,并查看哪种技术最适合您。只需确保您了解某种技术对您施加的限制(破坏的参照一致性,禁止的类型,必需的注释,必需的默认构造函数/ getter / setter等)。
MicroStream没有任何*。

(*)原因:在技术上可能的情况下,有意排除序列化/存储系统内部(例如线程)或非实体(例如lambda或代理实例)的可能性。

关于java - MicroStream(反序列化)如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58735841/

相关文章:

Java SQL 语句问题

java - 使用相应的专用 "beans"文件进行设置时,单个 spring "properties"属性值被覆盖(使用@PropertySource)

java - Kotlin: Unresolved reference :ofInstant

java - 以 '/' 字符作为 JSON 键的 Jackson ObjectMapper

java - 如何从其他 .war 访问 .war 中存在的 .jar?

serialization - JSON.NET 序列化失败

c++ - boost::序列化前后 Hook

python - 如何在 RESTful Flask 应用程序中将 Pandas DataFrame 序列化/反序列化为 ProtoBuf/Gzip?

java - 序列化 PHP => 反序列化 JAVA/Serialize for php in string format

c# - 如何将货币列表从 openexchangerates.org 反序列化为 C# 自定义类或对象?