Skip to content

Commit 4553a26

Browse files
committed
port xmlunit/#236
1 parent 82ca1c0 commit 4553a26

2 files changed

Lines changed: 29 additions & 11 deletions

File tree

RELEASE_NOTES.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## XMLUnit.NET 2.9.1 - /not released, yet/
44

5+
* improved comparison performance for documents with many siblings
6+
based on a suggestion by [@gerpres](https://github.com/gerpres) made
7+
in Java Issue [xmlunit/#236](https://github.com/xmlunit/xmlunit/issues/236)
8+
59
* added a new `FullDescription` method to `Diff` that provides a
610
string-representation of all differences - not just the first one
711
like `ToString` does.

src/main/net-core/Diff/DOMDifferenceEngine.cs

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -472,16 +472,22 @@ private ComparisonState CompareNodeLists(IEnumerable<XmlNode> allControlChildren
472472
IList<XmlNode> testListForXpath = new List<XmlNode>(allTestChildren);
473473
IList<XmlNode> controlList = new List<XmlNode>(controlSeq);
474474
IList<XmlNode> testList = new List<XmlNode>(testSeq);
475+
476+
IDictionary<XmlNode, int> controlListForXpathIndex = Index(controlListForXpath);
477+
IDictionary<XmlNode, int> testListForXpathIndex = Index(testListForXpath);
478+
IDictionary<XmlNode, int> controlListIndex = Index(controlList);
479+
IDictionary<XmlNode, int> testListIndex = Index(testList);
480+
475481
ICollection<XmlNode> seen = new HashSet<XmlNode>();
476482
foreach (KeyValuePair<XmlNode, XmlNode> pair in matches) {
477483
XmlNode control = pair.Key;
478484
seen.Add(control);
479485
XmlNode test = pair.Value;
480486
seen.Add(test);
481-
int controlIndexForXpath = controlListForXpath.IndexOf(control);
482-
int testIndexForXpath = testListForXpath.IndexOf(test);
483-
int controlIndex = controlList.IndexOf(control);
484-
int testIndex = testList.IndexOf(test);
487+
int controlIndexForXpath = controlListForXpathIndex[control];
488+
int testIndexForXpath = testListForXpathIndex[test];
489+
int controlIndex = controlListIndex[control];
490+
int testIndex = testListIndex[test];
485491
controlContext.NavigateToChild(controlIndexForXpath);
486492
testContext.NavigateToChild(testIndexForXpath);
487493
try {
@@ -500,13 +506,13 @@ private ComparisonState CompareNodeLists(IEnumerable<XmlNode> allControlChildren
500506
}
501507

502508
return chain
503-
.AndThen(UnmatchedControlNodes(controlListForXpath, controlList, controlContext,
509+
.AndThen(UnmatchedControlNodes(controlListForXpathIndex, controlList, controlContext,
504510
seen, testContext))
505-
.AndThen(UnmatchedTestNodes(testListForXpath, testList, testContext, seen,
506-
controlContext));
511+
.AndThen(UnmatchedTestNodes(testListForXpathIndex, testList, testContext,
512+
seen, controlContext));
507513
}
508514

509-
private Func<ComparisonState> UnmatchedControlNodes(IList<XmlNode> controlListForXpath,
515+
private Func<ComparisonState> UnmatchedControlNodes(IDictionary<XmlNode, int> controlListForXpathIndex,
510516
IList<XmlNode> controlList,
511517
XPathContext controlContext,
512518
ICollection<XmlNode> seen,
@@ -517,7 +523,7 @@ private Func<ComparisonState> UnmatchedControlNodes(IList<XmlNode> controlListFo
517523
for (int i = 0; i < controlSize; i++) {
518524
if (!seen.Contains(controlList[i])) {
519525
controlContext
520-
.NavigateToChild(controlListForXpath.IndexOf(controlList[i]));
526+
.NavigateToChild(controlListForXpathIndex[controlList[i]]);
521527
try {
522528
chain = chain
523529
.AndThen(new Comparison(ComparisonType.CHILD_LOOKUP,
@@ -536,7 +542,7 @@ private Func<ComparisonState> UnmatchedControlNodes(IList<XmlNode> controlListFo
536542
};
537543
}
538544

539-
private Func<ComparisonState> UnmatchedTestNodes(IList<XmlNode> testListForXpath,
545+
private Func<ComparisonState> UnmatchedTestNodes(IDictionary<XmlNode, int> testListForXpathIndex,
540546
IList<XmlNode> testList,
541547
XPathContext testContext,
542548
ICollection<XmlNode> seen,
@@ -546,7 +552,7 @@ private Func<ComparisonState> UnmatchedTestNodes(IList<XmlNode> testListForXpath
546552
int testSize = testList.Count;
547553
for (int i = 0; i < testSize; i++) {
548554
if (!seen.Contains(testList[i])) {
549-
testContext.NavigateToChild(testListForXpath.IndexOf(testList[i]));
555+
testContext.NavigateToChild(testListForXpathIndex[testList[i]]);
550556
try {
551557
chain = chain
552558
.AndThen(new Comparison(ComparisonType.CHILD_LOOKUP,
@@ -737,5 +743,13 @@ private static XmlAttribute FindMatchingAttr(IList<XmlAttribute> attrs,
737743
return null;
738744
}
739745

746+
private static IDictionary<XmlNode, int> Index(IList<XmlNode> nodes) {
747+
IDictionary<XmlNode, int> indices = new Dictionary<XmlNode, int>();
748+
int idx = 0;
749+
foreach (XmlNode n in nodes) {
750+
indices[n] = idx++;
751+
}
752+
return indices;
753+
}
740754
}
741755
}

0 commit comments

Comments
 (0)