Adds a test for using querySelectorAll instead of getElementById. Faster, but
still not as fast as a crawl.
Also "corrects" the DOCTYPE (thought I had done so already), which seems to slow
down web kit's dom api calls!!
Reviewed by jgw
http://gwt-code-reviews.appspot.com/128807
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7393 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Microbenchmarks.java b/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Microbenchmarks.java
index 2f2cc81..6e7505d 100644
--- a/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Microbenchmarks.java
+++ b/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Microbenchmarks.java
@@ -51,7 +51,8 @@
@UiField DeckPanel deck;
@UiField Button button;
@UiField Element running;
- @UiField Element elapsed;
+ @UiField Element runs;
+ @UiField Element sum;
@UiHandler("listBox")
public void onChange(@SuppressWarnings("unused") ChangeEvent ignored) {
@@ -68,11 +69,13 @@
public void execute() {
double start = Duration.currentTimeMillis();
benchmarks[index].run();
+ double end = Duration.currentTimeMillis();
UIObject.setVisible(running, false);
button.setEnabled(true);
- double end = Duration.currentTimeMillis();
- elapsedMs += end - start;
- elapsed.setInnerText(Util.format(elapsedMs));
+ double run = end - start;
+ runs.setInnerText(runs.getInnerText() + Util.format(run) + " ");
+ elapsedMs += run;
+ sum.setInnerText("(" + Util.format(elapsedMs) + ")");
}
});
}
diff --git a/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Microbenchmarks.ui.xml b/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Microbenchmarks.ui.xml
index 30f5785..70c51e4 100644
--- a/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Microbenchmarks.ui.xml
+++ b/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Microbenchmarks.ui.xml
@@ -5,7 +5,7 @@
<div style='margin-left:1em; margin-top:1em;'>
Select Benchmark: <gwt:ListBox ui:field='listBox'/>
<gwt:Button ui:field='button'>Run</gwt:Button>
- <span ui:field='elapsed'></span>
+ <span ui:field='runs'/><span ui:field='sum'/>
<span style="display:none; color:gray; font-style:oblique"
ui:field='running'>Running...</span>
</div>
diff --git a/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/TestDom.java b/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/TestDomInnerHtmlById.java
similarity index 90%
rename from reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/TestDom.java
rename to reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/TestDomInnerHtmlById.java
index 1ecadfe..14ad279 100644
--- a/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/TestDom.java
+++ b/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/TestDomInnerHtmlById.java
@@ -24,13 +24,13 @@
/**
* Run by {@link WidgetCreation}, see {@link Maker#name} for details.
*/
-public class TestDom extends Widget {
+public class TestDomInnerHtmlById extends Widget {
public static class Maker extends WidgetCreation.Maker {
Maker() {
- super("Text heavy UI via innerHTML, no widgets, get children by id");
+ super("Text heavy UI via innerHTML, no widgets, getElementById");
}
public Widget make() {
- return new TestDom();
+ return new TestDomInnerHtmlById();
}
}
@@ -44,7 +44,7 @@
SpanElement span2;
- private TestDom() {
+ private TestDomInnerHtmlById() {
root = Util.fromHtml(Util.TEXTY_OUTER_HTML);
Document.get().getBody().appendChild(root);
diff --git a/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/TestDomInnerHtmlQuerySelectorAll.java b/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/TestDomInnerHtmlQuerySelectorAll.java
new file mode 100644
index 0000000..868fc50
--- /dev/null
+++ b/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/TestDomInnerHtmlQuerySelectorAll.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.reference.microbenchmark.client;
+
+import com.google.gwt.core.client.JsArray;
+import com.google.gwt.dom.client.DivElement;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.SpanElement;
+import com.google.gwt.user.client.ui.Widget;
+
+/**
+ * Run by {@link WidgetCreation}, see {@link Maker#name} for details.
+ */
+public class TestDomInnerHtmlQuerySelectorAll extends Widget {
+ public static class Maker extends WidgetCreation.Maker {
+ Maker() {
+ super("Text heavy UI via innerHTML, no widgets, querySelectorAll");
+ }
+ public Widget make() {
+ return new TestDomInnerHtmlQuerySelectorAll();
+ }
+ }
+
+ Element root;
+ DivElement div1;
+ DivElement div2;
+ DivElement div3;
+
+ DivElement div4;
+ SpanElement span1;
+
+ SpanElement span2;
+
+ private TestDomInnerHtmlQuerySelectorAll() {
+ root = Util.fromHtml(Util.TEXTY_OUTER_HTML);
+
+ String query = "#div1, #div2, #div3, #div4, #span1, #span2";
+ JsArray<Element> response = Util.querySelectorAll(root, query);
+ assert 6 == response.length() : "response length should be 6: " + response.length();
+
+ div1 = response.get(0).cast();
+ div2 = response.get(1).cast();
+ span1 = response.get(2).cast();
+ div3 = response.get(3).cast();
+ div4 = response.get(4).cast();
+ span2 = response.get(5).cast();
+
+ assert div1.getId().equals("div1");
+ assert div2.getId().equals("div2");
+ assert span1.getId().equals("span1");
+ assert div3.getId().equals("div3");
+ assert div4.getId().equals("div4");
+ assert span2.getId().equals("span2");
+
+ div1.removeAttribute("id");
+ div2.removeAttribute("id");
+ span1.removeAttribute("id");
+ div3.removeAttribute("id");
+ div4.removeAttribute("id");
+ span2.removeAttribute("id");
+
+ setElement(root);
+ }
+}
diff --git a/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Util.java b/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Util.java
index 84fd4e0..87749d6 100644
--- a/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Util.java
+++ b/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Util.java
@@ -1,13 +1,17 @@
package com.google.gwt.reference.microbenchmark.client;
+import com.google.gwt.core.client.JsArray;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.Node;
import com.google.gwt.i18n.client.NumberFormat;
class Util {
private static final DivElement detachedDiv = Document.get().createDivElement();
+ static final boolean hasQSA = hasQSA();
+
static final String EMPTY_OUTER_HTML = "<div>" + Util.EMPTY_INNER_HTML + "</div>";
static final String EMPTY_INNER_HTML = "<div id='div1'>"
@@ -22,7 +26,7 @@
+ "</div>";
static final String TEXTY_OUTER_HTML = "<div>" + Util.TEXTY_INNER_HTML + "</div>";
-
+
static final String TEXTY_INNER_HTML = "Div root start"
+ "<div id='div1'>Div1 start"
+ "<div id='div2'>Div2</div>"
@@ -35,10 +39,14 @@
+ "Div 3 end</div>"
+ "Div anon end</div>"
+ "Div root end";
-
+
static void addText(Element elm, String text) {
elm.appendChild(Document.get().createTextNode(text));
}
+
+ static String format(double median) {
+ return NumberFormat.getFormat("0").format(median);
+ }
static Element fromHtml(String html) {
Util.detachedDiv.setInnerHTML(html);
@@ -47,18 +55,23 @@
return e;
}
- static long roundToTens(double median) {
- return Math.round(median/10)*10;
- }
-
- static String format(double median) {
- return NumberFormat.getFormat("0").format(median);
- }
-
static String outerHtml(Element e) {
String string = "<" + e.getNodeName() + ">"
+ e.getInnerHTML()
+ "</" + e.getNodeName() + ">";
return string;
}
+
+ static native JsArray<Element> querySelectorAll(Node root, String selector) /*-{
+ return root.querySelectorAll(selector);
+ }-*/;
+
+ static long roundToTens(double median) {
+ return Math.round(median/10)*10;
+ }
+
+ private static native boolean hasQSA() /*-{
+ var qsa = document.querySelectorAll;
+ return !(null == qsa);
+ }-*/;
}
diff --git a/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/WidgetCreation.java b/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/WidgetCreation.java
index 12459ca..149acc5 100644
--- a/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/WidgetCreation.java
+++ b/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/WidgetCreation.java
@@ -32,7 +32,10 @@
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.Date;
+import java.util.List;
/**
* Compares various widget creation strategies.
@@ -62,27 +65,43 @@
final Grid grid;
final TextBox number;
- final Maker[] makers = {
- new Maker("SimplePanel") {
- public Widget make() {
- return new SimplePanel();
- }
- }, new Maker("FlowPanel") {
- public Widget make() {
- return new FlowPanel();
- }
- }, new Maker("HTMLPanel") {
- public Widget make() {
- return new HTMLPanel("");
- }
- }, new EmptyBinder.Maker(), new TestEmptyDomViaApi.Maker(),
- new TestEmptyDom.Maker(),
- new TestEmptyCursorDomCrawl.Maker(),
- new TestEmptyRealisticDomCrawl.Maker(),new TestDomViaApi.Maker(),
- new TestDom.Maker(), new TestCursorDomCrawl.Maker(),
- new TestRealisticDomCrawl.Maker(), new TestDomBinder.Maker(),
- new TestFlows.Maker(), new TestManualHTMLPanel.Maker(),
- new TestWidgetBinder.Maker()};
+ final List<Maker> makers;
+ {
+ List<Maker> makeMakers = new ArrayList<Maker>();
+ makeMakers.add(new Maker("SimplePanel") {
+ public Widget make() {
+ return new SimplePanel();
+ }
+ });
+ makeMakers.add(new Maker("FlowPanel") {
+ public Widget make() {
+ return new FlowPanel();
+ }
+ });
+ makeMakers.add(new Maker("HTMLPanel") {
+ public Widget make() {
+ return new HTMLPanel("");
+ }
+ });
+ makeMakers.add(new EmptyBinder.Maker());
+ makeMakers.add(new TestEmptyDomViaApi.Maker());
+ makeMakers.add(new TestEmptyDom.Maker());
+ makeMakers.add(new TestEmptyCursorDomCrawl.Maker());
+ makeMakers.add(new TestEmptyRealisticDomCrawl.Maker());
+ makeMakers.add(new TestDomViaApi.Maker());
+ makeMakers.add(new TestDomInnerHtmlById.Maker());
+ if (Util.hasQSA) {
+ makeMakers.add(new TestDomInnerHtmlQuerySelectorAll.Maker());
+ }
+ makeMakers.add(new TestCursorDomCrawl.Maker());
+ makeMakers.add(new TestRealisticDomCrawl.Maker());
+ makeMakers.add(new TestDomBinder.Maker());
+ makeMakers.add(new TestFlows.Maker());
+ makeMakers.add(new TestManualHTMLPanel.Maker());
+ makeMakers.add(new TestWidgetBinder.Maker());
+
+ makers = Collections.unmodifiableList(makeMakers);
+ }
final private FlowPanel root;
@@ -108,7 +127,7 @@
}
});
- grid = new Grid(makers.length + 1, 3);
+ grid = new Grid(makers.size() + 2, 3);
grid.setText(0, 0, "50%");
grid.setText(0, 1, "m");
@@ -141,20 +160,21 @@
}
public void run() {
- RootPanel r = RootPanel.get();
+ RootPanel root = RootPanel.get();
Widget[] widgets = new Widget[getInstances()];
grid.resizeColumns(grid.getColumnCount() + 1);
int row = 1;
+ double allTimes = 0;
for (Maker maker : makers) {
log(maker.name);
double start = Duration.currentTimeMillis();
for (int i = 0; i < getInstances(); ++i) {
widgets[i] = maker.make();
- r.add(widgets[i]);
+ root.add(widgets[i]);
}
/*
@@ -167,14 +187,16 @@
double thisTime = Duration.currentTimeMillis() - start;
record(row, thisTime);
+ allTimes += thisTime;
// Clean up to keep the dom a reasonable size.
for (int i = 0; i < getInstances(); ++i) {
- r.remove(widgets[i]);
+ root.remove(widgets[i]);
}
row++;
}
+ grid.setText(row, grid.getColumnCount() - 1, Util.format(allTimes));
}
private int getInstances() {
diff --git a/reference/Microbenchmarks/war/Microbenchmarks.html b/reference/Microbenchmarks/war/Microbenchmarks.html
index 07ccef6..dddd1e2 100644
--- a/reference/Microbenchmarks/war/Microbenchmarks.html
+++ b/reference/Microbenchmarks/war/Microbenchmarks.html
@@ -1,4 +1,4 @@
-<!DOCTYPE>
+<!DOCTYPE HTML>
<html>
<head>