使用Xerces C++计算/访问DOMNode儿童的最快方法
Fastest way to count/ access DOMNode children using Xerces C++
我正在尝试找出计算Xerces C++ DOMNode对象的子元素数量的最快方法,因为我正在尝试优化使用Xerces 2.6 DOMParser的Windows应用程序的性能。
似乎大部分时间都花在计数和访问孩子上。我们的应用程序需要迭代文档中的每个节点,以使用DOMNode::setUserData()
将数据附加到其中,我们最初使用DOMNode::getChildNodes()
、DOMNodeList::getLength()
和DOMNodeList::item(int index)
来计数和访问子节点,但这些都是相对昂贵的操作。
当我们使用不同的调用习语时,观察到性能大幅提高 DOMNode:: getFirstChild()
获取第一个子节点并调用DOMNode::getNextSibling()
以访问特定索引处的子节点,或者计算第一个子元素的同级元素的同级节点数以获取子节点总数。
但是,getNextSibling()
仍然是我们解析步骤中的瓶颈,所以我想知道是否有一种更快的方法来使用 Xerces 遍历和访问子元素。
DOMNodeList
的问题在于,它实际上是一个非常简单的列表,因此像 length
和 item(i)
这样的操作具有O(n)
的成本,如代码所示,例如这里的长度:
XMLSize_t DOMNodeListImpl::getLength() const{
XMLSize_t count = 0;
if (fNode) {
DOMNode *node = fNode->fFirstChild;
while(node != 0){
++count;
node = castToChildImpl(node)->nextSibling;
}
}
return count;
}
因此,如果不希望在迭代时更改 DOM 树,则不应使用 DOMNodeList
,因为访问 O(n)
中的项目从而使迭代成为O(n^2)
操作 - 等待发生的灾难(即足够大的 xml 文件(。
使用 DOMNode::getFistChild()
和 DOMNode::getNextSibling()
对于迭代来说是一个足够好的解决方案:
DOMNode *child = docNode->getFirstChild();
while (child != nullptr) {
// do something with the node
...
child = child->getNextSibling();
}
这在O(n)
中按预期发生.
也可以使用 DOMNodeIterator
,但为了创建它,需要正确的DOMDocument
,这在需要迭代时并不总是在手边。
是的,在我发布后不久,我添加了代码来存储和管理每个节点的子计数,这产生了很大的不同。重复访问相同的节点,并且每次都重新计算子节点计数。这是一个相当昂贵的操作,因为Xerces本质上是为该节点重建DOM结构以保证其活动。我们有自己的对象,它封装了一个Xerces DOMNode以及我们需要的额外信息,我们使用DOMNode::setUserData将我们的对象与相关的DOMnode相关联,现在这似乎是最后一个瓶颈。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 通过方法访问结构
- 最小硬币更换问题(自上而下方法)
- C++为构建时间获取QDateTime的可靠方法
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 有什么方法可以遍历结构吗
- 当类在C++中定义时,有什么方法可以"register"类吗?
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- 使用std::函数映射对象方法
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- C++从另一个类访问公共静态向量的正确方法是什么
- C++优先级队列,按对象的唯一指针的特定方法升序排列
- 没有为自己的结构调用列表推回方法
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 在类定义之后定义一个私有方法
- 枚举环境变量的惯用C++14/C++17方法
- 使用Xerces C++计算/访问DOMNode儿童的最快方法