我试图找出计算Xerces C++ DOMNode对象的子元素数量的最快方法,因为我试图优化使用Xerces 2.6 DOMParser的Windows应用程序的性能。
似乎大部分时间都花在计算和访问孩子上。我们的应用程序需要迭代文档中的每个节点,以使用DOMNode::setUserData()
将数据附加到它,我们最初使用DOMNode::getChildNodes()
,DOMNodeList::getLength()
和DOMNodeList::item(int index)
来计数和访问子节点,但这些操作相对昂贵。
当我们使用另一种方法调用DOMNode:: getFirstChild()
来获取第一个子节点,然后调用DOMNode::getNextSibling()
来访问特定索引处的子节点,或者计算第一个子元素的兄弟节点的数量以获得子节点总数时,我们观察到了很大的性能提升。
然而,getNextSibling()
仍然是我们解析步骤中的一个瓶颈,所以我想知道是否有一种更快的方法来使用Xerces遍历和访问子元素。
2条答案
按热度按时间brgchamk1#
DOMNodeList
的问题是,它实际上是一个非常简单的列表,因此像length
和item(i)
这样的操作有O(n)
的成本,可以在代码中看到,例如这里的长度:因此,如果不希望DOM树在迭代时发生更改,则不应使用
DOMNodeList
,因为访问O(n)
中的项从而使迭代成为O(n^2)
操作-等待发生的灾难(即足够大的XML文件)。使用
DOMNode::getFistChild()
和DOMNode::getNextSibling()
是一个足够好的迭代解决方案:这在
O(n)
中如预期的那样发生。也可以使用
DOMNodeIterator
,但是为了创建它,需要正确的DOMDocument
,当需要迭代时,它并不总是在手边。rqenqsqc2#
是的,在我发布后不久,我添加了代码来存储和管理每个节点的子计数,这产生了很大的不同。重复访问相同的节点,每次都重新计算子节点计数。这是一个相当昂贵的操作,因为Xerces基本上为该节点重新构建DOM结构以保证其活性。我们有自己的对象,它封装了一个Xerces DOMNode沿着我们需要的额外信息,我们使用DOMNode::setUserData将我们的对象与相关的DOMnode相关联,现在这似乎是最后剩下的瓶颈。