Revision: 7393
Author: [email protected]
Date: Wed Jan 13 13:58:25 2010
Log: 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
http://code.google.com/p/google-web-toolkit/source/detail?r=7393

Added:
/trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/TestDomInnerHtmlById.java /trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/TestDomInnerHtmlQuerySelectorAll.java
Deleted:
/trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/TestDom.java
Modified:
/trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Microbenchmarks.java /trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Microbenchmarks.ui.xml /trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Util.java /trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/WidgetCreation.java
 /trunk/reference/Microbenchmarks/war/Microbenchmarks.html

=======================================
--- /dev/null
+++ /trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/TestDomInnerHtmlById.java Wed Jan 13 13:58:25 2010
@@ -0,0 +1,68 @@
+/*
+ * 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.dom.client.DivElement;
+import com.google.gwt.dom.client.Document;
+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 TestDomInnerHtmlById extends Widget {
+  public static class Maker extends WidgetCreation.Maker {
+    Maker() {
+      super("Text heavy UI via innerHTML, no widgets, getElementById");
+    }
+    public Widget make() {
+      return new TestDomInnerHtmlById();
+    }
+  }
+
+  Element root;
+  DivElement div1;
+  DivElement div2;
+  DivElement div3;
+
+  DivElement div4;
+  SpanElement span1;
+
+  SpanElement span2;
+
+  private TestDomInnerHtmlById() {
+    root = Util.fromHtml(Util.TEXTY_OUTER_HTML);
+
+    Document.get().getBody().appendChild(root);
+    div1 = Document.get().getElementById("div1").cast();
+    div2 = Document.get().getElementById("div2").cast();
+    div3 = Document.get().getElementById("div3").cast();
+    div4 = Document.get().getElementById("div4").cast();
+    span1 = Document.get().getElementById("span1").cast();
+    span2 = Document.get().getElementById("span2").cast();
+
+    Document.get().getBody().removeChild(root);
+    div1.removeAttribute("id");
+    div2.removeAttribute("id");
+    div3.removeAttribute("id");
+    div4.removeAttribute("id");
+    span1.removeAttribute("id");
+    span2.removeAttribute("id");
+
+    setElement(root);
+  }
+}
=======================================
--- /dev/null
+++ /trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/TestDomInnerHtmlQuerySelectorAll.java Wed Jan 13 13:58:25 2010
@@ -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);
+  }
+}
=======================================
--- /trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/TestDom.java Thu Jan 7 14:15:09 2010
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.dom.client.DivElement;
-import com.google.gwt.dom.client.Document;
-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 TestDom extends Widget {
-  public static class Maker extends WidgetCreation.Maker {
-    Maker() {
-      super("Text heavy UI via innerHTML, no widgets, get children by id");
-    }
-    public Widget make() {
-      return new TestDom();
-    }
-  }
-
-  Element root;
-  DivElement div1;
-  DivElement div2;
-  DivElement div3;
-
-  DivElement div4;
-  SpanElement span1;
-
-  SpanElement span2;
-
-  private TestDom() {
-    root = Util.fromHtml(Util.TEXTY_OUTER_HTML);
-
-    Document.get().getBody().appendChild(root);
-    div1 = Document.get().getElementById("div1").cast();
-    div2 = Document.get().getElementById("div2").cast();
-    div3 = Document.get().getElementById("div3").cast();
-    div4 = Document.get().getElementById("div4").cast();
-    span1 = Document.get().getElementById("span1").cast();
-    span2 = Document.get().getElementById("span2").cast();
-
-    Document.get().getBody().removeChild(root);
-    div1.removeAttribute("id");
-    div2.removeAttribute("id");
-    div3.removeAttribute("id");
-    div4.removeAttribute("id");
-    span1.removeAttribute("id");
-    span2.removeAttribute("id");
-
-    setElement(root);
-  }
-}
=======================================
--- /trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Microbenchmarks.java Thu Jan 7 14:15:09 2010 +++ /trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Microbenchmarks.java Wed Jan 13 13:58:25 2010
@@ -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) + ")");
       }
     });
   }
=======================================
--- /trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Microbenchmarks.ui.xml Thu Jan 7 14:15:09 2010 +++ /trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Microbenchmarks.ui.xml Wed Jan 13 13:58:25 2010
@@ -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>
=======================================
--- /trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Util.java Thu Jan 7 14:15:09 2010 +++ /trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Util.java Wed Jan 13 13:58:25 2010
@@ -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);
@@ -46,14 +54,6 @@
     e.getParentElement().removeChild(e);
     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() + ">"
@@ -61,4 +61,17 @@
     + "</" + 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);
+  }-*/;
+}
=======================================
--- /trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/WidgetCreation.java Thu Jan 7 14:15:09 2010 +++ /trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/WidgetCreation.java Wed Jan 13 13:58:25 2010
@@ -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() {
=======================================
--- /trunk/reference/Microbenchmarks/war/Microbenchmarks.html Tue Jan 5 10:30:31 2010 +++ /trunk/reference/Microbenchmarks/war/Microbenchmarks.html Wed Jan 13 13:58:25 2010
@@ -1,4 +1,4 @@
-<!DOCTYPE>
+<!DOCTYPE HTML>

 <html>
   <head>
-- 
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to