决定何时使用XmlDocument vs XmlReader

Phi*_*ang 61 c# xmldocument xmlreader xml-serialization

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

它通过将文件加载到XmlDocument对象中,然后递归遍历所有子节点来工作.

我认为也许使用XmlReader而不是XmlDocument加载/解析整个事情会更快,所以我也实现了那个版本.

算法完全相同,我使用包装类来抽象处理一个XmlNode与一个的功能XmlReader.例如,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);
    }
}
Run Code Online (Sandbox Code Playgroud)

该测试适用于单个级别的许多对象(即宽和浅) - 但是我想知道XmlReader当XML深入和广泛时票价如何?即我正在处理的XML很像数据对象模型,许多子对象的1个父对象,等等:1..M..M..M

我还事先不知道我正在解析的XML的结构,所以我无法对其进行优化.

Zac*_*ham 69

我一般都是从最快的角度来看,而是从内存利用的角度来看.对于我在其中使用的使用场景(典型的企业集成),所有实现都足够快.

然而,在我失败的时候,有时甚至是惊人的,并没有考虑到我正在使用的XML的一般大小.如果你事先考虑一下,你可以省去一些悲伤.

XML倾向于在被加载到存储器,至少带有DOM读取器等,以臃肿XmlDocumentXPathDocument.像10:1这样的东西?确切的数量难以量化,但如果它在磁盘上为1MB,则内存为10MB或更多.

使用任何将整个文档整体加载到内存中的读取器(XmlDocument/ XPathDocument)的进程可能遭受大对象堆碎片的影响,这最终会导致OutOfMemoryExceptions(即使有可用内存)导致服务/进程不可用.

由于大于85K的对象最终会出现在大对象堆上,并且您使用DOM读取器进行了10:1的大小爆炸,因此您可以看到在分配XML文档之前不需要花费太多时间.大对象堆.

XmlDocument很容易使用.它唯一的缺点是它将整个XML文档加载到内存中进行处理.它诱人的使用简单.

XmlReader 是一个基于流的阅读器,所以将保持您的进程内存利用率通常更平坦,但更难以使用.

XPathDocument 往往是一个更快,只读版本的XmlDocument,但仍然遭受内存'膨胀'.

  • 将XML文档(无论多大)加载到内存中不会导致大型对象.然而,将XML作为字符串保存!相对于GC对内存进行碎片整理的能力而言,各个对象的大小是重要的,但对于内存使用而言,对象图的总大小是重要的. (4认同)

DSO*_*DSO 11

XmlDocument是整个XML文档的内存中表示形式.因此,如果您的文档很大,那么它将比使用XmlReader读取它时消耗更多的内存.

这假设当您使用XmlReader时,您逐个读取并处理元素,然后丢弃它.如果您使用XmlReader并在内存中构建另一个中间结构,那么您遇到了同样的问题,并且您正在破坏它的目的.

谷歌为" SAX与DOM "更多地了解了处理XML的两种模式之间的差异.