我正在优化自定义对象-> XML序列化实用程序,它已经完成并且可以正常工作了,这不是问题。

它的工作方式是将文件加载到XmlDocument对象中,然后递归遍历所有子节点。

我发现也许使用XmlReader而不是XmlDocument加载/解析整个过程会更快,所以我也实现了该版本。

算法完全相同,我使用包装器类来抽象处理XmlNodeXmlReader的功能。例如,GetChildren方法yield返回子XmlNode或SubTree XmlReader

因此,我编写了一个测试驱动程序来测试这两个版本,并使用非平凡的数据集(一个900kb的XML文件,其中包含约1,350个元素)。

但是,使用JetBrains dotTRACE,我发现XmlReader版本实际上比XmlDocument版本慢!遍历子节点时,XmlReader读取调用似乎涉及一些重要处理。

因此,我想问的一切都是这样:

XmlDocumentXmlReader的优点/缺点是什么,在什么情况下应使用哪种?

我的猜测是,存在一个文件大小阈值,在该阈值下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至少在使用诸如XmlDocumentXPathDocument之类的DOM读取器加载到内存时趋于膨胀。像10:1一样?确切的数量很难量化,但是例如,如果磁盘上为1MB,则其内存将为10MB,甚至更多。

使用任何读取器将整个文档全部加载到内存中的过程(XmlDocument/XPathDocument)可能会受到大型对象堆碎片的影响,最终可能导致OutOfMemoryException(即使有可用内存),从而导致服务/进程不可用。



XmlDocument 非常易于使用。它唯一的真正缺点是它将整个XML文档加载到内存中进行处理。它诱人的简单易用。

XmlReader 是基于流的读取器,因此将使您的进程内存利用率总体上趋于平坦,但更难使用。

XPathDocument 趋向于是XmlDocument的更快的只读版本,但仍然遭受内存“膨胀”的困扰。

关于c# - 确定何时使用XmlDocument和XmlReader,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1505075/

10-11 22:38
查看更多