决定何时使用XmlDocument与XmlReader
我正在优化自定义对象 - > XML序列化实用程序,这一切都已经完成并且工作,这不是问题。
它通过将文件加载到XmlDocument
对象中,然后递归遍历所有子节点来工作。
我想,也许使用XmlReader
而不是让XmlDocument
加载/解析整个事情会更快,所以我也实现了该版本。
算法完全一样,我使用包装类来抽象处理XmlNode
和XmlReader
。 例如, GetChildren
方法的yield返回一个子XmlNode
或一个SubTree XmlReader
。
所以我编写了一个测试驱动程序来测试这两个版本,并使用一个非平凡的数据集(一个约有1,350个元素的900kb XML文件)。
但是,使用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);
}
}
该测试适用于单个级别的很多对象(即宽和浅) - 但是我不知道XmlReader
在XML深度和广度上的表现如何? 即我正在处理的XML非常像数据对象模型,对许多子对象有一个父对象,等等: 1..M..M..M
我也不知道我正在解析的XML的结构,所以我无法对它进行优化。
我一般不是从最快的角度来看待它 ,而是从内存利用的角度来看。 所有的实现对于我使用它们的典型企业集成中的使用场景来说足够快。
但是,在我堕落的地方,有时甚至是令人惊叹的地方,并没有考虑到我正在使用的XML的大小。 如果你事先考虑一下,你可以节省一些悲伤。
XML在加载到内存时往往会膨胀,至少使用XmlDocument
或XPathDocument
等DOM阅读器。 像10:1? 确切的数量很难量化,但是如果它在磁盘上是1MB,则它将在内存中为10MB或更多,例如。
使用任何将整个文档加载到内存中的读取器( XmlDocument
/ XPathDocument
)的进程可能会遇到大对象堆碎片,最终可能导致OutOfMemoryException
(即使存在可用内存)导致不可用的服务/进程。
由于大小超过85K的对象最终放置在大型对象堆中,并且DOM读取器的大小为10:1,所以您可以看到在分配XML文档之前它并不需要太多时间大对象堆。
XmlDocument
非常易于使用。 它唯一的缺点是它将整个XML文档加载到内存中进行处理。 它的诱惑性简单易用。
XmlReader
是一个基于流的阅读器,因此会保持您的进程内存利用率通常更平坦,但更难以使用。
XPathDocument
往往是XmlDocument的更快,只读的版本,但仍受内存“膨胀”的影响。
XmlDocument是整个XML文档的内存中表示。 因此,如果您的文档很大,那么它将消耗比使用XmlReader读取更多的内存。
这是假设当你使用XmlReader时,你读取并逐个处理元素,然后丢弃它。 如果你使用XmlReader并在内存中构造另一个中间结构,那么你也有同样的问题,并且你打败了它的目的。
Google针对“SAX vs. DOM”来详细了解这两种处理XML模型的区别。
另一个考虑是XMLReader对于处理不完全形成的XML可能更加健壮。 我最近创建了一个客户端,它使用了一个XML流,但是该流没有在包含在某些元素中的URI中正确转义的特殊字符。 XMLDocument和XPathDocument完全拒绝加载XML,而使用XMLReader我能够从流中提取所需的信息。
链接地址: http://www.djcxy.com/p/29913.html