`Serializable` 对象的更快序列化

Posted

技术标签:

【中文标题】`Serializable` 对象的更快序列化【英文标题】:Faster serialization of `Serializable` objects 【发布时间】:2014-10-06 05:58:44 【问题描述】:

我们的客户端/服务器应用使用NetDataContractSerializer 序列化任意Serializable 对象。

BinaryFormatter 的输出会更小一些,however 的性能并不是真正的better。

现在可以使用更小的表示形式(例如,XmlSerializerDataContractSerializer、Json、Protocol Buffers、Thrift 等的输出),这也恰好可以更快地进行序列化和反序列化。

但是,为了使用这些,我必须访问每个 Serializable 类并添加属性并可能更改字段的访问级别等。这些类不仅分布在许多不同的内部项目中,但是我们的客户有自己的带有Serializable 类的dll,必须对其进行修改。换言之,一项重大事业。

Serializable 对象是否有任何其他性能改进和潜在的尺寸减小(gzipping 等除外)?

【问题讨论】:

【参考方案1】:

我在查看 Lars Kemmann 的建议后得出的结论:除了NetDataContractSerializer/BinaryFormatter 之外,没有其他选择可以以相同的方式序列化和反序列化。

我和Json.NET 玩过,它有点工作,但通常情况下,魔鬼在细节中(另请参阅我的 cmets 对 Lars 的回答):

用现实生活中的对象进行测试,结果发现我的反序列化对象并非 100% 等同于原始对象,源于未序列化的超类中的字段。至少粗略检查后是这样的。

Protobuf-net 也不是一个选项,因为你

    必须在序列化之前手动注册每个(非 protobuf 注释的)类型 在反序列化时必须指定确切的类型 它抱怨没有无参数构造函数的类

【讨论】:

【参考方案2】:

其中许多序列化程序不需要自定义属性 - 事实上,有些是专门设计用于识别和使用 SerializableAttribute。参见,例如:

JSON.NET's documented support of SerializableAttribute protobuf-net's approach 允许运行时配置并且还支持DataContractAttribute(它更准确地定义了您在有线协议中想要的特性)。你当然可以在运行时配置 protobuf-net 来做你想做的事。

Json.NET 示例:

var settings = new JsonSerializerSettings
 
    TypeNameHandling = TypeNameHandling.All,
    PreserveReferencesHandling = PreserveReferencesHandling.Objects,
;
string serialized = JsonConvert.SerializeObject(obj, settings);
var deserialized = JsonConvert.DeserializeObject(serialized, settings);

更新:您不需要 fork Json.NET 来进行类型实例化。我正在使用this article 中所述的自定义JsonConverter

【讨论】:

引用您的 protobuf 链接:Contract types Protobuf-net expects contract types to be explicitly marked as such; types can be marked [ProtoContract], [DataContract] or [XmlType] for this purpose ([Serializable] is not required and is not used) 我就是这么说的。还引用了该 protobuf 项目 wiki 页面的第一行:“请注意,在 v2 中,所有内容也可以在运行时配置,而无需编辑任何类型。” 我可以让 Json.NET 工作(并在您的答案中添加了一个示例),但在 protobuf-net 的情况下,我 a) 似乎必须添加每个(非 protobuf-annotated)类型在序列化之前手动 b)在反序列化时指定确切的类型(例如,不是常见的超级接口/类) c)protobuf 抱怨,除非有无参数的构造函数。 IE。它似乎不能替代 BinaryFormatter/NetDataContractSerializer。 感谢您添加。是的,绝对有可能的限制。如果您正在寻找性能更好且行为没有任何重大变化的直接替代品,我认为您不会找到 - 微软的性能工程师获得高薪是有原因的。 :) 我会说绝对值得考虑添加[DataContract] 注释的好处,因为正如我所说[Serializable] 真的不适合有线传输,除非您确定要紧密耦合您的客户端和服务器。 [DataContract] 将打开更多选项。 好吧,我不确定 NetDataContractSerializerJson.NET 是否 100% 等效,但在我使用实际复杂的嵌套对象进行的测试中,前者花费的时间是后者的 1.5 倍,这让我有点惊讶,因为 MS 可以在内部做很多 Json.NET 做不到的“不安全”的事情。

以上是关于`Serializable` 对象的更快序列化的主要内容,如果未能解决你的问题,请参考以下文章

Android Parcelable 和 Serializable

Android高级技巧-intent传递对象

Serializable java序列化

关于java的序列化

关于java的Serializable

Serializable作用