【问题标题】:XML vs Binary performance for Serialization/Deserialization序列化/反序列化的 XML 与二进制性能
【发布时间】:2010-11-08 16:28:30
【问题描述】:

我正在开发一个紧凑的框架应用程序,需要提高性能。该应用程序当前通过将对象序列化为 XML 并将它们存储在数据库中来离线工作。使用分析工具,我可以看到这是相当大的开销,减慢了应用程序的速度。我想如果我切换到二进制序列化,性能会提高,但是因为紧凑框架不支持这点,所以我查看了 protobuf-net。序列化似乎更快,但反序列化要慢得多,并且应用程序的反序列化比序列化更多。

二进制序列化是否应该更快,如果是,我可以做些什么来加快性能?这是我如何使用 XML 和二进制文件的 sn-p:

XML 序列化:

public string Serialize(T obj)
{
  UTF8Encoding encoding = new UTF8Encoding();
  XmlSerializer serializer = new XmlSerializer(typeof(T));
  MemoryStream stream = new MemoryStream();
  XmlTextWriter writer = new XmlTextWriter(stream, Encoding.UTF8);
  serializer.Serialize(stream, obj);
  stream = (MemoryStream)writer.BaseStream;
  return encoding.GetString(stream.ToArray(), 0, Convert.ToInt32(stream.Length));
}
public T Deserialize(string xml)
{
  UTF8Encoding encoding = new UTF8Encoding();
  XmlSerializer serializer = new XmlSerializer(typeof(T));
  MemoryStream stream = new MemoryStream(encoding.GetBytes(xml));            
  return (T)serializer.Deserialize(stream);
}

Protobuf-net 二进制序列化:

public byte[] Serialize(T obj)
{
  byte[] raw;
  using (MemoryStream memoryStream = new MemoryStream())
  {
    Serializer.Serialize(memoryStream, obj);
    raw = memoryStream.ToArray();
  }

  return raw;            
}

public T Deserialize(byte[] serializedType)
{
  T obj;
  using (MemoryStream memoryStream = new MemoryStream(serializedType))
  {
    obj = Serializer.Deserialize<T>(memoryStream);
  }
  return obj;
}

【问题讨论】:

  • 我本来建议使用 Red-Gate ANTS profiler 但它不适用于 Compact 框架(在 google 上搜索“red-gate ant profiler compact”)

标签: c# .net serialization compact-framework protobuf-net


【解决方案1】:

有趣的……想法:

  • 这是什么版本的CF; 2.0? 3.5?特别是,CF 3.5 有 Delegate.CreateDelegate,它允许 protobuf-net 访问属性的速度比 CF 2.0 中的快得多
  • 您是在注释 fields 还是 properties?同样,在 CF 中,反射优化是有限的。您可以使用 properties 在 CF 3.5 中获得更好的性能,因为我唯一可用的选项是 FieldInfo.SetValue

还有很多其他的东西在 CF 中根本不存在,所以它不得不在一些地方做出妥协。对于过于复杂的模型,还有一个known issue with the generics limitations of CF。修复正在进行中,但这是一个更改,并且需要“一段时间”。

有关信息,常规(完整).NET 上的一些指标比较各种格式(包括XmlSerializer 和 protobuf-net)are here

【讨论】:

  • 我使用的是 CF2.0,并且我已经为我需要序列化的对象的属性添加了属性。
  • 是否可以在 CF 3.5(使用 CF 3.5 二进制文件)中尝试,看看是否能解决问题?
  • 好的,我刚刚在 CF3.5 上运行了测试,发现 CF2 的性能显着提高; binary 在序列化和反序列化方面执行得更快。不幸的是,我与 CF2 有联系,所以可能不得不重新考虑。
  • 只是为了澄清我上面的措辞.. 我的意思是我看到 CF3.5 的性能显着提高; CF2 较慢。
  • 对不起..从头开始,我读错了性能报告!这是我测试一个具有 3 个属性的简单实体的结果: XML 序列化 317 毫秒 XML 反序列化:7 毫秒二进制序列化:147 毫秒二进制反序列化:19 毫秒
【解决方案2】:

您是否尝试过为您的类创建自定义序列化类?而不是使用 XmlSerializer 这是一个通用的序列化器(它在运行时创建一堆类)。有一个工具可以做到这一点(sgen)。您在构建过程中运行它,它会生成一个可用于 XmlSerializer 的自定义程序集。

如果您有 Visual Studio,则该选项位于项目属性的“构建”选项卡下。

【讨论】:

    【解决方案3】:

    序列化对象或将它们写入数据库是否会影响性能?由于编写它们可能会遇到某种缓慢的存储,我想它比序列化步骤更大。

    请记住,Marc Gravell 发布的性能测量正在测试超过 1,000,000 次迭代的性能。

    您将它们存储在哪种数据库中?对象是在内存中序列化还是直接存储?它们是如何被发送到数据库的?物体有多大?当一个对象被更新时,你是把所有的对象都发送到数据库,还是只发送一个已经改变的对象?您是在内存中缓存任何内容,还是每次都从存储中重新读取?

    【讨论】:

    • 对象被存储在 SQLCe 数据库中,但我可以清楚地看到序列化和反序列化是性能损失,而不是数据库交互。内容也被缓存在内存中,但需要将内容存储在数据库中,以便可以在应用程序的会话之间检索。
    【解决方案4】:

    我要纠正自己,Marc Gravall 指出第一次迭代有构建模型的开销,所以我做了一些测试,对 XML 和二进制进行平均 1000 次序列化和反序列化迭代。我首先使用 Compact Framework DLL 的 v2 进行了测试,然后使用了 v3.5 DLL。这是我得到的,时间以毫秒为单位:

    .NET 2.0
    ================================ XML ====== Binary ===
    Serialization 1st Iteration      3236       5508
    Deserialization 1st Iteration    1501       318
    Serialization Average            9.826      5.525
    Deserialization Average          5.525      0.771
    
    .NET 3.5
    ================================ XML ====== Binary ===
    Serialization 1st Iteration      3307       5598
    Deserialization 1st Iteration    1386       200
    Serialization Average            10.923     5.605
    Deserialization Average          5.605      0.279
    

    【讨论】:

      【解决方案5】:

      XML 通常处理速度很慢并且占用大量空间。已经有许多不同的尝试来解决这个问题,而今天最流行的似乎是将很多内容放入 gzip 文件中,例如 Open Packaging Convention

      W3C 表明 gzip 方法不是最优的,他们和各种other groups 一直在致力于更好的二进制序列化,适合快速处理和压缩,用于传输。

      【讨论】:

        【解决方案6】:

        您的方法中的主要开销是 XmlSerializer 类的实际生成。创建序列化器是一个耗时的过程,您应该为每个对象类型只做一次。尝试缓存序列化程序,看看这是否能提高性能。

        按照这个建议,我看到我的应用程序的性能有了很大的提升,这让我可以继续使用 XML 序列化。

        希望这会有所帮助。

        【讨论】:

          猜你喜欢
          • 2014-01-04
          • 2011-01-14
          • 1970-01-01
          • 1970-01-01
          • 2012-11-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-12-31
          相关资源
          最近更新 更多