Skip to content

Commit 681f38f

Browse files
committed
Add more Jsoup benchmarks
1 parent af66a5c commit 681f38f

9 files changed

+192
-9
lines changed

src/io/sf/carte/mark/dom/DOMChangeMark.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,15 @@ private void change(DOMImplementation domImpl) {
6363
if (root == null) {
6464
throw new IllegalStateException("Document has no element child.");
6565
}
66-
//
66+
6767
for (int i = 0; i < 20000; i++) {
6868
Element element = doc.createElement("element");
6969
element.setAttribute("foo", "bar");
7070
Text text = doc.createTextNode("text");
7171
element.appendChild(text);
7272
root.appendChild(element);
7373
}
74-
//
74+
7575
for (int i = 0; i < 20000; i++) {
7676
Node element = root.getFirstChild();
7777
root.removeChild(element);
@@ -85,17 +85,17 @@ public void markChangeJsoup() {
8585
if (body == null) {
8686
throw new IllegalStateException("Document has no body.");
8787
}
88-
//
88+
8989
for (int i = 0; i < 20000; i++) {
9090
org.jsoup.nodes.Element element = doc.createElement("element");
9191
element.attr("foo", "bar");
9292
TextNode text = TextNode.createFromEncoded("text");
9393
element.appendChild(text);
9494
body.appendChild(element);
9595
}
96-
//
96+
9797
for (int i = 0; i < 20000; i++) {
98-
org.jsoup.nodes.Element element = body.child(0);
98+
org.jsoup.nodes.Element element = body.firstElementChild();
9999
element.remove();
100100
}
101101
}

src/io/sf/carte/mark/dom/DOMDataSmall.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222
@State(Scope.Benchmark)
2323
public class DOMDataSmall extends DocumentData {
2424

25-
public org.jsoup.nodes.Document jsoupDoc;
26-
2725
public DOMDataSmall() {
2826
super("/io/sf/carte/mark/dom/xhtml1.xml", false, 1566, 713, "li", 55);
2927
}

src/io/sf/carte/mark/dom/DOMElementsByTagNameMark.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
package io.sf.carte.mark.dom;
1313

14+
import org.jsoup.nodes.Element;
15+
import org.jsoup.select.Elements;
1416
import org.openjdk.jmh.annotations.Benchmark;
1517
import org.openjdk.jmh.annotations.Fork;
1618
import org.openjdk.jmh.annotations.Measurement;
@@ -84,4 +86,38 @@ public void markElementsByTagNameDOMit(DOMData data) {
8486
}
8587
}
8688

89+
@Benchmark
90+
public void markElementsByTagNameJsoup(DOMData data) {
91+
int count = 0;
92+
Elements list = data.jsoupDoc.getElementsByTag(data.getTagName());
93+
int n = list.size();
94+
for (int i = 0; i < n; i++) {
95+
Element element = list.get(i);
96+
// The following test is silly but could prevent optimizations
97+
if (!data.getTagName().equals(element.nodeName())) {
98+
throw new IllegalStateException();
99+
}
100+
count++;
101+
}
102+
if (count != data.nameCount) {
103+
throw new IllegalStateException("Expected a count of " + data.nameCount + ", obtained " + count);
104+
}
105+
}
106+
107+
@Benchmark
108+
public void markElementsByTagNameJsoupIt(DOMData data) {
109+
int count = 0;
110+
Elements list = data.jsoupDoc.getElementsByTag(data.getTagName());
111+
for (Element element : list) {
112+
// The following test is silly but could prevent optimizations
113+
if (!data.getTagName().equals(element.nodeName())) {
114+
throw new IllegalStateException();
115+
}
116+
count++;
117+
}
118+
if (count != data.nameCount) {
119+
throw new IllegalStateException("Expected a count of " + data.nameCount + ", obtained " + count);
120+
}
121+
}
122+
87123
}

src/io/sf/carte/mark/dom/DOMIteratorMark.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@
1212
package io.sf.carte.mark.dom;
1313

1414
import java.util.Iterator;
15+
import java.util.List;
1516

1617
import org.dom4j.Branch;
18+
import org.jsoup.nodes.Element;
19+
import org.jsoup.select.Elements;
1720
import org.openjdk.jmh.annotations.Benchmark;
1821
import org.openjdk.jmh.annotations.Fork;
1922
import org.openjdk.jmh.annotations.Measurement;
@@ -119,4 +122,43 @@ private int iterateDOM4JElements(org.dom4j.Element element, int count) {
119122
return count;
120123
}
121124

125+
@Benchmark
126+
public void markIteratorJsoup(DOMDataSmall data) {
127+
int count = iterateJsoup(data.jsoupDoc.childNodes(), 0);
128+
if (count < data.minimumCount) {
129+
throw new IllegalStateException(
130+
"Expected a count of at least " + data.minimumCount + " obtained " + count);
131+
}
132+
}
133+
134+
private int iterateJsoup(List<org.jsoup.nodes.Node> list, int count) {
135+
if (!list.isEmpty()) {
136+
Iterator<org.jsoup.nodes.Node> it = list.iterator();
137+
while (it.hasNext()) {
138+
count++;
139+
count = iterateJsoup(it.next().childNodes(), count);
140+
}
141+
}
142+
return count;
143+
}
144+
145+
@Benchmark
146+
public void markElementIteratorJsoup(DOMDataSmall data) {
147+
int count = iterateJsoupElements(data.jsoupDoc.children(), 0);
148+
if (count != data.elementCount + 3) {
149+
throw new IllegalStateException(
150+
"Expected a count of " + data.elementCount + ", obtained " + count);
151+
}
152+
}
153+
154+
private int iterateJsoupElements(Elements elements, int count) {
155+
Iterator<Element> it = elements.iterator();
156+
while (it.hasNext()) {
157+
Element child = it.next();
158+
count++;
159+
count = iterateJsoupElements(child.children(), count);
160+
}
161+
return count;
162+
}
163+
122164
}

src/io/sf/carte/mark/dom/DOMSiblingTraversalMark.java

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public void markTraverseDOM4J(DOMData data) {
5252
}
5353
}
5454

55-
private int traverse(Node node, int count) {
55+
private static int traverse(Node node, int count) {
5656
Node child = node.getFirstChild();
5757
while (child != null) {
5858
count++;
@@ -62,6 +62,26 @@ private int traverse(Node node, int count) {
6262
return count;
6363
}
6464

65+
@Benchmark
66+
public void markTraverseJsoup(DOMData data) {
67+
org.jsoup.nodes.Node child = data.jsoupDoc.firstElementChild();
68+
int count = traverseJsoup(child, 0);
69+
if (count < data.minimumCount) {
70+
throw new IllegalStateException(
71+
"Expected a count of " + data.minimumCount + " obtained " + count);
72+
}
73+
}
74+
75+
private static int traverseJsoup(org.jsoup.nodes.Node node, int count) {
76+
org.jsoup.nodes.Node child = node.firstChild();
77+
while (child != null) {
78+
count++;
79+
count = traverseJsoup(child, count);
80+
child = child.nextSibling();
81+
}
82+
return count;
83+
}
84+
6585
@Benchmark
6686
public void markTraversePrevJdk(DOMData data) {
6787
Node node = data.jdkDoc.getDocumentElement();
@@ -100,4 +120,24 @@ private int traversePrev(Node node, int count) {
100120
return count;
101121
}
102122

123+
@Benchmark
124+
public void markTraversePrevJsoup(DOMData data) {
125+
org.jsoup.nodes.Node child = data.jsoupDoc.firstElementChild();
126+
int count = traversePrevJsoup(child, 0);
127+
if (count < data.minimumCount) {
128+
throw new IllegalStateException(
129+
"Expected a count of " + data.minimumCount + " obtained " + count);
130+
}
131+
}
132+
133+
private static int traversePrevJsoup(org.jsoup.nodes.Node node, int count) {
134+
org.jsoup.nodes.Node child = node.lastChild();
135+
while (child != null) {
136+
count++;
137+
count = traversePrevJsoup(child, count);
138+
child = child.previousSibling();
139+
}
140+
return count;
141+
}
142+
103143
}

src/io/sf/carte/mark/dom/DOMSiblingTraversalSmallMark.java

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public void markTraverseDOM4J(DOMDataSmall data) {
5252
}
5353
}
5454

55-
private int traverse(Node node, int count) {
55+
private static int traverse(Node node, int count) {
5656
Node child = node.getFirstChild();
5757
while (child != null) {
5858
count++;
@@ -62,6 +62,26 @@ private int traverse(Node node, int count) {
6262
return count;
6363
}
6464

65+
@Benchmark
66+
public void markTraverseJsoup(DOMData data) {
67+
org.jsoup.nodes.Node child = data.jsoupDoc.firstElementChild();
68+
int count = traverseJsoup(child, 0);
69+
if (count < data.minimumCount) {
70+
throw new IllegalStateException(
71+
"Expected a count of " + data.minimumCount + " obtained " + count);
72+
}
73+
}
74+
75+
private static int traverseJsoup(org.jsoup.nodes.Node node, int count) {
76+
org.jsoup.nodes.Node child = node.firstChild();
77+
while (child != null) {
78+
count++;
79+
count = traverseJsoup(child, count);
80+
child = child.nextSibling();
81+
}
82+
return count;
83+
}
84+
6585
@Benchmark
6686
public void markTraversePrevJdk(DOMDataSmall data) {
6787
Node node = data.jdkDoc.getDocumentElement();
@@ -100,4 +120,24 @@ private int traversePrev(Node node, int count) {
100120
return count;
101121
}
102122

123+
@Benchmark
124+
public void markTraversePrevJsoup(DOMData data) {
125+
org.jsoup.nodes.Node child = data.jsoupDoc.firstElementChild();
126+
int count = traversePrevJsoup(child, 0);
127+
if (count < data.minimumCount) {
128+
throw new IllegalStateException(
129+
"Expected a count of " + data.minimumCount + " obtained " + count);
130+
}
131+
}
132+
133+
private static int traversePrevJsoup(org.jsoup.nodes.Node node, int count) {
134+
org.jsoup.nodes.Node child = node.lastChild();
135+
while (child != null) {
136+
count++;
137+
count = traversePrevJsoup(child, count);
138+
child = child.previousSibling();
139+
}
140+
return count;
141+
}
142+
103143
}

src/io/sf/carte/mark/dom/DocumentData.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import org.dom4j.DocumentException;
2222
import org.dom4j.io.SAXReader;
23+
import org.jsoup.Jsoup;
2324
import org.w3c.dom.DOMImplementation;
2425
import org.w3c.dom.Document;
2526
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
@@ -55,6 +56,8 @@ public class DocumentData {
5556

5657
Document dom4jDoc;
5758

59+
org.jsoup.nodes.Document jsoupDoc;
60+
5861
DocumentData(String filename, boolean compressed, int minimumCount, int elementCount, String tagName,
5962
int nameCount) {
6063
super();
@@ -81,6 +84,7 @@ public void init() {
8184
jdkDoc = loadJdkDocument(documentText, entityResolver);
8285
dom4jDoc = loadDOM4JDocument(documentText, entityResolver);
8386
domDoc = loadDOMDocument(documentText, entityResolver);
87+
jsoupDoc = loadJsoupDocument(documentText);
8488
}
8589

8690
private static Document loadJdkDocument(String documentText, EntityResolver entityResolver) {
@@ -162,4 +166,9 @@ private static Document loadDOM4JDocument(String documentText, EntityResolver en
162166
}
163167
return doc;
164168
}
169+
170+
private static org.jsoup.nodes.Document loadJsoupDocument(String documentText) {
171+
return Jsoup.parse(documentText);
172+
}
173+
165174
}

src/io/sf/carte/mark/dom/XMLBuildBenchmark.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import org.dom4j.DocumentException;
2424
import org.dom4j.io.SAXReader;
25+
import org.jsoup.Jsoup;
2526
import org.openjdk.jmh.annotations.Benchmark;
2627
import org.openjdk.jmh.annotations.Fork;
2728
import org.openjdk.jmh.annotations.Measurement;
@@ -146,4 +147,12 @@ public void markBuildCss4jDOM4J() throws IOException, DocumentException, ParserC
146147
}
147148
}
148149

150+
@Benchmark
151+
public void markBuildJsoup() throws IOException {
152+
org.jsoup.nodes.Document doc = Jsoup.parse(documentText);
153+
if (doc == null) {
154+
throw new RuntimeException();
155+
}
156+
}
157+
149158
}

src/io/sf/carte/mark/dom/XMLBuildSmallBenchmark.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import org.dom4j.DocumentException;
2424
import org.dom4j.io.SAXReader;
25+
import org.jsoup.Jsoup;
2526
import org.openjdk.jmh.annotations.Benchmark;
2627
import org.openjdk.jmh.annotations.Fork;
2728
import org.openjdk.jmh.annotations.Measurement;
@@ -145,4 +146,12 @@ public void markBuildCss4jDOM4J() throws IOException, DocumentException, ParserC
145146
}
146147
}
147148

149+
@Benchmark
150+
public void markBuildJsoup() throws IOException {
151+
org.jsoup.nodes.Document doc = Jsoup.parse(documentText);
152+
if (doc == null) {
153+
throw new RuntimeException();
154+
}
155+
}
156+
148157
}

0 commit comments

Comments
 (0)