我们有一个应用程序需要在启动时加载大量配置数据。数据存储在XML文件中,该文件目前为40MB,但将增长到100MB甚至更多。这些数据在开发时会发生变化,但在发布之间不会
我们正在寻找一种方法来加快“固定”数据集的加载过程,并且一个想法导致了这个问题:
将xml文件转换为可以作为二进制文件传递的内容的最简单/最有效的方法是什么?
例如,我们可以在其初始化方法中生成一个包含大量“new objectFromXML(param1,param2,...,paramn)”行的静态类,或者我们可以使用一个包含数据的巨大数组的对象。所有这一切都可以毫无困难地完成,但我怀疑我们的问题有更优雅的解决方案。任何评论都将受到高度赞赏。
答案 0 :(得分:3)
protobuf-net可以在相同的类定义*上同时兼容二进制(Google的高效“协议缓冲区”格式)和xml。
如果您的xml是基于元素的并且包含[XmlElement(Order = 1)]
等属性,它甚至可以在没有任何更改的情况下工作(为了工作,它需要能够找到每个属性的唯一编号,您看到)。请注意,如果您使用继承([XmlInclude]
),则需要添加其他属性(同样,要提名一个数字 - 通过类似的[ProtoInclude]
)
否则,您可以添加其他属性,并完成工作;只需致电Serializer.Serialize
。
Result:更小,更快的序列化。
* =并且作为证明,这实际上是codegen的工作方式:将“.proto”DSL编译为二进制(“protoc”),将二进制文件加载到对象模型(“protobuf-net”)中,写为xml(XmlSerializer
),通过xslt运行以获取C#。
替代方法可能是将xml通过xslt运行到C#中并编译它,但是......丑陋。我绝对需要的时候自己这样做了;破坏反射器真是太可怕了! (no, really)。
答案 1 :(得分:1)
我的第一反应是:为什么??? 40 MB的XML文件已经非常庞大。为什么甚至会在其中存储更多数据? 处理这么多数据的好方法是使用数据库。 SQL Server Express可以免费安装,并且可以更快地运行。如果您不需要完整的服务器,可以选择SQL Server的Compact版本,因为它基本上允许XCopy部署。
XML的唯一优势是它对机器和人类都是可读的。使用二进制格式,您将需要一些额外的工具来使其具有人类可读性。
由于您使用的是C#,我只是选择SQL Server Compact版本,其中的SQL脚本会在数据库中添加大量逻辑关系和约束。另外一个Entity Framework类将使数据更易于访问,并且在某些XML配置文件中您唯一需要的是连接字符串...
<小时/> 但是如果你坚持使用这个XML文件,那么已经建议使用ZLIB来压缩整个文件。
答案 2 :(得分:1)
这个想法是在xml中写入数据,但是将xml转换为字节流作为构建步骤。您可以通过将xml加载到内存中对象中,然后将该对象的二进制序列化作为文件来执行此操作。在生产中只需进行二进制反序列化并完全跳过xml。
答案 3 :(得分:1)
如果您想加快加载过程,压缩XML不会对您有所帮助。事实上,它会伤害到你:你的程序不必简单地解析XML,而是必须解压缩然后解析它。
你真的没有提供有关你目前正在做什么的非常多的信息。您目前是否正在将XML加载到XmlDocument
或XDocument
中,然后对其进行处理?如果是这样,加速加载而不改变其他任何东西的最简单方法是实现一个使用XmlReader
的加载方法,它允许您同时解析和反序列化数据。
您是否使用XML序列化来生成XML?如果是这样,您可以使用协议缓冲区,如Marc Gravell建议的那样,或者您可以实现二进制序列化。这假定您不需要XML用于任何其他目的。
在程序运行之前,您是否真的需要反序列化所有配置数据?或者是否可以使用某种延迟加载方法?如果你可以进行延迟加载,那么选择一些序列化格式可以让你将加载过程分解为在程序需要时执行的块,这可以加快程序的表面性能(如果不是实际性能)。
我想底线是:有几十种可能的问题方法,定义为“我需要在启动时从XML文档中加载大量数据”。更准确地定义问题,您将获得更多有用的建议。
答案 4 :(得分:0)
有没有想过使用Resource file来代替你自己的自制XML文件?这几乎就是他们要做的事情。
答案 5 :(得分:0)
我最终使用zlib以二进制格式创建XML和XSD文件的压缩副本。
答案 6 :(得分:0)
如果您希望将XML转换为某种对象结构,您可以从双方中的一方获取它。首先,如果您主要使用XML中的节点,则可以为XML创建XSD,然后使用XSD.exe工具生成用于序列化/反序列化此代码的代码。第二个选项是设置与XML格式匹配的简单POCO对象,只需使用XmlSerializer将XML转换为对象。
答案 7 :(得分:-1)
VTD-XML具有内置的索引功能,名为vtd + xml,基本思想是将XML解析为VTD,然后将VTD与XML一起保存到索引文件中...下次加载索引时XML文档,您不必解析它,这会显着加快解析速度...请参阅下面的文章