69

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

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

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

算法完全相同,我使用包装类来抽象处理 anXmlNode与 an的功能XmlReader。例如,GetChildren方法 yield 返回一个 childXmlNode或一个 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);
    }
}

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

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

4

5 回答 5

74

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

然而,我失败的地方,有时是惊人的,没有考虑到我正在使用的 XML 的一般大小。如果您事先考虑一下,您可以为自己节省一些悲伤。

XML 在加载到内存时往往会膨胀,至少对于 DOM 阅读器,如XmlDocumentor XPathDocument。10:1之类的?确切的数量很难量化,但如果它是 1MB 在磁盘上,那么它将是 10MB 在内存中,或者更多,例如。

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

由于大小超过 85K 的对象最终位于大对象堆上,并且您使用 DOM 阅读器获得了 10:1 的大小爆炸,您可以看到在分配 XML 文档之前不需要太多时间大对象堆。

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

XmlReader是基于流的阅读器,因此可以使您的进程内存利用率通常更平坦,但更难使用。

XPathDocument往往是 XmlDocument 的更快的只读版本,但仍然存在内存“膨胀”的问题。

于 2009-10-01T20:35:10.733 回答
11

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

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

谷歌“ SAX 与 DOM ”阅读更多关于处理 XML 的两种模型之间的差异。

于 2009-10-01T20:08:32.390 回答
4

另一个考虑因素是 XMLReader 对于处理格式不完美的 XML 可能更加健壮。我最近创建了一个使用 XML 流的客户端,但该流在某些元素中包含的 URI 中没有正确转义特殊字符。XMLDocument 和 XPathDocument 根本拒绝加载 XML,而使用 XMLReader 我能够从流中提取我需要的信息。

于 2015-04-13T16:03:07.097 回答
0

有一个大小阈值,在该阈值处 XmlDocument 变得更慢,最终无法使用。但是阈值的实际值将取决于您的应用程序和 XML 内容,因此没有硬性规定。

如果您的 XML 文件可以包含大型列表(例如数万个元素),那么您绝对应该使用 XmlReader。

于 2009-10-01T16:43:27.340 回答
0

编码差异是因为混合了两种不同的测量值。UTF-32 每个字符需要 4 个字节,本质上比单字节数据慢。

如果您查看大型 (100K) 元素测试,您会发现无论使用何种加载方法,每种情况的时间都增加了大约 70mS。

这是一个(几乎)恒定的差异,具体由每个字符的开销引起,

于 2012-11-11T15:52:28.947 回答