Skip to content

Commit 81513d5

Browse files
perf: Use Set for stopNodes lookup (O(1)) instead of array iteration (O(n)) (#769)
1 parent 77703c4 commit 81513d5

File tree

1 file changed

+21
-10
lines changed

1 file changed

+21
-10
lines changed

src/xmlparser/OrderedObjParser.js

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,20 @@ export default class OrderedObjParser{
5555
this.saveTextToParentTag = saveTextToParentTag;
5656
this.addChild = addChild;
5757
this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes)
58+
59+
if(this.options.stopNodes && this.options.stopNodes.length > 0){
60+
this.stopNodesExact = new Set();
61+
this.stopNodesWildcard = new Set();
62+
for(let i = 0; i < this.options.stopNodes.length; i++){
63+
const stopNodeExp = this.options.stopNodes[i];
64+
if(typeof stopNodeExp !== 'string') continue;
65+
if(stopNodeExp.startsWith("*.")){
66+
this.stopNodesWildcard.add(stopNodeExp.substring(2));
67+
}else{
68+
this.stopNodesExact.add(stopNodeExp);
69+
}
70+
}
71+
}
5872
}
5973

6074
}
@@ -313,7 +327,7 @@ const parseXml = function(xmlData) {
313327
jPath += jPath ? "." + tagName : tagName;
314328
}
315329
const startIndex = i;
316-
if (this.isItStopNode(this.options.stopNodes, jPath, tagName)) {
330+
if (this.isItStopNode(this.stopNodesExact, this.stopNodesWildcard, jPath, tagName)) {
317331
let tagContent = "";
318332
//self-closing tag
319333
if(tagExp.length > 0 && tagExp.lastIndexOf("/") === tagExp.length - 1){
@@ -451,17 +465,14 @@ function saveTextToParentTag(textData, currentNode, jPath, isLeafNode) {
451465

452466
//TODO: use jPath to simplify the logic
453467
/**
454-
*
455-
* @param {string[]} stopNodes
468+
* @param {Set} stopNodesExact
469+
* @param {Set} stopNodesWildcard
456470
* @param {string} jPath
457-
* @param {string} currentTagName
471+
* @param {string} currentTagName
458472
*/
459-
function isItStopNode(stopNodes, jPath, currentTagName){
460-
const allNodesExp = "*." + currentTagName;
461-
for (const stopNodePath in stopNodes) {
462-
const stopNodeExp = stopNodes[stopNodePath];
463-
if( allNodesExp === stopNodeExp || jPath === stopNodeExp ) return true;
464-
}
473+
function isItStopNode(stopNodesExact, stopNodesWildcard, jPath, currentTagName){
474+
if(stopNodesWildcard && stopNodesWildcard.has(currentTagName)) return true;
475+
if(stopNodesExact && stopNodesExact.has(jPath)) return true;
465476
return false;
466477
}
467478

0 commit comments

Comments
 (0)