我正在优化自定义对象-> XML序列化实用程序,它已经完成并且可以正常工作了,这不是问题。
它的工作方式是将文件加载到XmlDocument
对象中,然后递归遍历所有子节点。
我发现也许使用XmlReader
而不是XmlDocument
加载/解析整个过程会更快,所以我也实现了该版本。
算法完全相同,我使用包装器类来抽象处理XmlNode
和XmlReader
的功能。例如,GetChildren
方法yield返回子XmlNode
或SubTree XmlReader
。
因此,我编写了一个测试驱动程序来测试这两个版本,并使用非平凡的数据集(一个900kb的XML文件,其中包含约1,350个元素)。
但是,使用JetBrains dotTRACE,我发现XmlReader
版本实际上比XmlDocument
版本慢!遍历子节点时,XmlReader
读取调用似乎涉及一些重要处理。
因此,我想问的一切都是这样:
XmlDocument
和XmlReader
的优点/缺点是什么,在什么情况下应使用哪种?
我的猜测是,存在一个文件大小阈值,在该阈值下XmlReader
的性能变得更经济,并且占用的内存更少。但是,该阈值似乎高于1MB。
我每次都调用ReadSubTree
来处理子节点:
public override IEnumerable<IXmlSourceProvider> GetChildren ()
{
XmlReader xr = myXmlSource.ReadSubtree ();
// skip past the current element
xr.Read ();
while (xr.Read ())
{
if (xr.NodeType != XmlNodeType.Element) continue;
yield return new XmlReaderXmlSourceProvider (xr);
}
}
该测试适用于单个级别(即宽和浅)的许多对象-但是我想知道当XML深和宽时
XmlReader
的效果如何?即我正在处理的XML很像数据对象模型,许多子对象有1个父对象,等等:1..M..M..M
我还事先不知道要解析的XML的结构,因此无法对其进行优化。
最佳答案
我一般不是从最快的角度来看它的,而是从内存利用率的角度来看的。对于我在(典型的企业集成)中使用过的使用场景而言,所有实现都足够快。
但是,我失败的地方(有时甚至是令人印象深刻的地方)没有考虑到我正在使用的XML的一般大小。如果您提前考虑一下,就可以避免一些麻烦。
XML至少在使用诸如XmlDocument
或XPathDocument
之类的DOM读取器加载到内存时趋于膨胀。像10:1一样?确切的数量很难量化,但是例如,如果磁盘上为1MB,则其内存将为10MB,甚至更多。
使用任何读取器将整个文档全部加载到内存中的过程(XmlDocument
/XPathDocument
)可能会受到大型对象堆碎片的影响,最终可能导致OutOfMemoryException
(即使有可用内存),从而导致服务/进程不可用。
XmlDocument
非常易于使用。它唯一的真正缺点是它将整个XML文档加载到内存中进行处理。它诱人的简单易用。
XmlReader
是基于流的读取器,因此将使您的进程内存利用率总体上趋于平坦,但更难使用。
XPathDocument
趋向于是XmlDocument的更快的只读版本,但仍然遭受内存“膨胀”的困扰。
关于c# - 确定何时使用XmlDocument和XmlReader,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1505075/