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

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

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

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

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

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

【问题讨论】:

    标签: .net serializable binaryformatter netdatacontractserializer


    【解决方案1】:

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

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

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

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

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

    【讨论】:

      【解决方案2】:

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

      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 做不到的“不安全”的事情。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-27
      • 1970-01-01
      • 1970-01-01
      • 2012-11-08
      • 2012-11-14
      • 1970-01-01
      • 2012-10-19
      相关资源
      最近更新 更多