C#:将对象序列化为XML而不进行反射



在应用程序中,我们可以保存应用程序的当前状态及其配置(可能很大)。我们正在使用XmlSerializer

我们现在在XML中只有我们需要的东西(所有XmlIgnore都已就位),并且存储整个配置(大约50-100MB的文件)非常慢。

我们需要继续将此配置存储为XML,但我们希望避免:

  • 反射,这是为了减缓
  • 实现IXmlSerializable接口

我们的想法是在每个对象中实现一个方法,在这个方法中,我们可以注册要序列化的字段/属性,然后有一个SerializationManager,它能够读取我们想要序列化的内容,然后编写它们。

像这样,对象不知道它们将用什么语言(XML)呈现,如果有一天我们想要二进制序列化(或者如果我们希望有可能以不同的格式序列化),我们可以。

但我们不想重新发明轮子,我不知道是否存在一些库,或者像Linq-to-xml这样的东西是否可以帮助我们,或者这是否是天生可能的。。。

那么你认为我该如何做到这一点呢?

"反射,这是为了减缓">

不过,它在运行时不使用反射。它在第一次运行时执行元编程(假设您使用的是new XmlSerializer(type)),以检查类型并生成适用于给定类型的静态代码。因此,任何与卷相关的性能问题都与反思无关。存在元编程本身可能需要可衡量的时间,但a:除非您的模型真的很复杂,否则这是不可能的,b:可以通过使用sgen.exe工具预生成序列化程序集来避免。

因此,任何性能问题都很可能是由于模型的大小和xml的开销造成的。

如果你想尝试不同的序列化程序,可以考虑像protobuf-net这样的东西。您将无法读取数据(它将不是xml),但输出将更小、更快。

正如您提到的

在应用程序中,我们可以保存应用程序的当前状态及其配置

状态,尤其是当它很大(100Mb…巨大!)时,需要自己的方式来序列化数据。我们中的许多人都知道并讨厌过去那种缓慢的保存/加载游戏保存。即使是现在,游戏开发人员也将快速保存与顺序保存区分开来。它被优化为比顺序保存发生得更快(例如,通过缓存最近执行的快速保存的一部分)。

第一个问题是为什么使用XML?BinarySerializer更快,但对于这样的大小,您最好使用手动序列化(正如Marc Gravell建议的那样,使用protobuf,它最终优于任何东西)。

第二个问题是,您真的需要序列化数据(更改它们的格式)吗?保存状态的最快方法是转储内存。想象一下,你把所有的数据都保存在一个内存块中,然后把这个块转储到一个文件中是一个非常快速的保存。你可以(我不确定,但它应该是可行的)以某种方式构建你的数据,覆盖这个内存的将是加载游戏。这比任何转换都快得多。

如果您使用转储,则考虑将其打包(放入zip)。打包和保存10 mb应该比保存未打包的100 mb快(假设你没有使用太慢或太好的打包算法),内存操作和cpu比SSD快得多。

要保存配置,您仍然可以像往常一样序列化它。如果您希望它是一个单独的文件,那么定义这个文件自己的格式,例如:

config_stream, separator["<<<>>>>"], memory block [100 Mb]

XmlSerializer序列化到内存中,创建文件,保存配置,分隔符,转储。

最新更新