Revision: 9925
Author: [email protected]
Date: Fri Apr 1 04:44:18 2011
Log: Adding table rendering tests to micro benchmarks. Table rendering
tests are multiple orders of magnitude slower than the existing basic
tests, so I seperated them into a seperate mirco benchmark. I modified
WidgetCreation so it could be used for both instead of copying udles of
code. You can see the app running at http://jlabanca-testing.appspot.com/.
I also made some changes to improve test accuracy. I found that the tests
get slower as elements are attached to the DOM and as the test runs, so
instead of running all iterations of a single test, we run all tests one
iteration at a time. We also alternate the order of the tests, so the last
test added isn't always the last test to run. Finally, we remove each
rendered widget after we add it and record the time, as the existence of a
widget could affect the timing of the next test. This seems to lead to more
reasonable numbers in practice.
Review at http://gwt-code-reviews.appspot.com/1394802
Review by: [email protected]
http://code.google.com/p/google-web-toolkit/source/detail?r=9925
Added:
/trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/TestCreateTableDom.java
/trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/TestCreateTableDomWithEvents.java
/trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/TestCreateTableInnerHtml.java
/trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/TestCreateTablePrecreatedInnerHtml.java
/trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/WidgetCreation.ui.xml
Modified:
/trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Microbenchmarks.java
/trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Util.java
/trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/WidgetCreation.java
=======================================
--- /dev/null
+++
/trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/TestCreateTableDom.java
Fri Apr 1 04:44:18 2011
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2011 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.TableCellElement;
+import com.google.gwt.dom.client.TableElement;
+import com.google.gwt.dom.client.TableRowElement;
+import com.google.gwt.dom.client.TableSectionElement;
+import com.google.gwt.user.client.ui.Widget;
+
+/**
+ * Run by {@link WidgetCreation}, see {@link
TestCreateTableDom.Maker#name} for
+ * details.
+ */
+public class TestCreateTableDom extends Widget {
+ public static class Maker extends WidgetCreation.Maker {
+ Maker() {
+ super(Util.TABLE_ROW_COUNT + "x" + Util.TABLE_COLUMN_COUNT
+ + " table via DOM api calls, no widgets");
+ }
+
+ @Override
+ public Widget make() {
+ return new TestCreateTableDom();
+ }
+ }
+
+ TestCreateTableDom() {
+ // This table should match the structure defined in
Util#createTableHtml().
+ TableElement table = Document.get().createTableElement();
+ TableSectionElement tbody = Document.get().createTBodyElement();
+ table.appendChild(tbody);
+ for (int row = 0; row < Util.TABLE_ROW_COUNT; row++) {
+ TableRowElement tr = Document.get().createTRElement();
+ tbody.appendChild(tr);
+ if (row % 2 == 0) {
+ tr.addClassName("evenRow");
+ } else {
+ tr.addClassName("oddRow");
+ }
+ for (int column = 0; column < Util.TABLE_COLUMN_COUNT; column++) {
+ TableCellElement td = Document.get().createTDElement();
+ td.setAlign("center");
+ td.setVAlign("middle");
+ td.appendChild(createCellContents(row, column));
+ }
+ }
+ setElement(table);
+ }
+
+ /**
+ * Create the contents of a cell.
+ *
+ * @param row the row index
+ * @param column the column index
+ * @return the cell contents as an element
+ */
+ Element createCellContents(int row, int column) {
+ DivElement div = Document.get().createDivElement();
+ div.setInnerHTML("Cell " + row + ":" + column);
+ return div;
+ }
+}
=======================================
--- /dev/null
+++
/trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/TestCreateTableDomWithEvents.java
Fri Apr 1 04:44:18 2011
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2011 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.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.Widget;
+
+/**
+ * Run by {@link WidgetCreation}, see
+ * {@link TestCreateTableDomWithEvents.Maker#name} for details.
+ */
+public class TestCreateTableDomWithEvents extends TestCreateTableDom {
+ public static class Maker extends WidgetCreation.Maker {
+
+ Maker() {
+ super(Util.TABLE_ROW_COUNT + "x" + Util.TABLE_COLUMN_COUNT
+ + " table via DOM api calls, no widgets, sink events on each
cell");
+ }
+
+ @Override
+ public Widget make() {
+ return new TestCreateTableDomWithEvents();
+ }
+ }
+
+ @Override
+ Element createCellContents(int row, int column) {
+ Element div = super.createCellContents(row, column);
+ Event.sinkEvents(div, Event.ONCLICK);
+ return div;
+ }
+}
=======================================
--- /dev/null
+++
/trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/TestCreateTableInnerHtml.java
Fri Apr 1 04:44:18 2011
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2011 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.user.client.ui.Widget;
+
+/**
+ * Run by {@link WidgetCreation}, see
+ * {@link TestCreateTableInnerHtml.Maker#name} for details.
+ */
+public class TestCreateTableInnerHtml extends Widget {
+ public static class Maker extends WidgetCreation.Maker {
+ Maker() {
+ super(Util.TABLE_ROW_COUNT + "x" + Util.TABLE_COLUMN_COUNT
+ + " table via innerHTML built with StringBuilder, no widgets");
+ }
+
+ @Override
+ public Widget make() {
+ return new TestCreateTableInnerHtml();
+ }
+ }
+
+ private TestCreateTableInnerHtml() {
+ setElement(Util.fromHtml(Util.createTableHtml()));
+ }
+}
=======================================
--- /dev/null
+++
/trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/TestCreateTablePrecreatedInnerHtml.java
Fri Apr 1 04:44:18 2011
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2011 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.user.client.ui.Widget;
+
+/**
+ * Run by {@link WidgetCreation}, see
+ * {@link TestCreateTablePrecreatedInnerHtml.Maker#name} for details.
+ */
+public class TestCreateTablePrecreatedInnerHtml extends Widget {
+ public static class Maker extends WidgetCreation.Maker {
+
+ private final String tableHtml = Util.createTableHtml();
+
+ Maker() {
+ super(Util.TABLE_ROW_COUNT + "x" + Util.TABLE_COLUMN_COUNT
+ + " table via precreated innerHTML String, no widgets");
+ }
+
+ @Override
+ public Widget make() {
+ return new TestCreateTablePrecreatedInnerHtml(tableHtml);
+ }
+ }
+
+ private TestCreateTablePrecreatedInnerHtml(String tableHtml) {
+ setElement(Util.fromHtml(tableHtml));
+ }
+}
=======================================
--- /dev/null
+++
/trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/WidgetCreation.ui.xml
Fri Apr 1 04:44:18 2011
@@ -0,0 +1,26 @@
+<ui:UiBinder
+ xmlns:ui='urn:ui:com.google.gwt.uibinder'
+ xmlns:g='urn:import:com.google.gwt.user.client.ui'>
+
+ <g:HTMLPanel
+ ui:field="root">
+ <b>
+ Time for creating, attaching and detaching
+ <g:TextBox
+ ui:field="number"
+ visibleLength="7" />
+ instances, in MS
+ </b>
+ <br />
+
+ <g:CheckBox
+ ui:field="includeLargeWidget">Click to include a large widget on the
page while running the
+ test</g:CheckBox>
+ <br />
+ <br />
+
+ <g:Grid
+ ui:field="grid" />
+ </g:HTMLPanel>
+
+</ui:UiBinder>
=======================================
---
/trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Microbenchmarks.java
Wed Jan 13 13:58:25 2010
+++
/trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Microbenchmarks.java
Fri Apr 1 04:44:18 2011
@@ -21,6 +21,7 @@
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.reference.microbenchmark.client.WidgetCreation.Maker;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
@@ -28,23 +29,26 @@
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DeckPanel;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RootPanel;
+import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwt.user.client.ui.Widget;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* Offers up a selection of {@link Microbenchmark} implementations to run.
*/
public class Microbenchmarks implements EntryPoint {
-
+
interface Binder extends UiBinder<Widget, Microbenchmarks> {}
private static final Binder BINDER = GWT.create(Binder.class);
-
- // Add entries for new benchmarks here.
- private final Microbenchmark[] benchmarks = {
- new WidgetCreation()
- };
+
+ private final Microbenchmark[] benchmarks;
double elapsedMs = 0;
@UiField ListBox listBox;
@@ -54,12 +58,62 @@
@UiField Element runs;
@UiField Element sum;
+ public Microbenchmarks() {
+ // Add entries for new widget benchmarks here.
+ List<Maker> widgetMakers = new ArrayList<Maker>();
+ widgetMakers.add(new Maker("SimplePanel") {
+ @Override
+ public Widget make() {
+ return new SimplePanel();
+ }
+ });
+ widgetMakers.add(new Maker("FlowPanel") {
+ @Override
+ public Widget make() {
+ return new FlowPanel();
+ }
+ });
+ widgetMakers.add(new Maker("HTMLPanel") {
+ @Override
+ public Widget make() {
+ return new HTMLPanel("");
+ }
+ });
+ widgetMakers.add(new EmptyBinder.Maker());
+ widgetMakers.add(new TestEmptyDomViaApi.Maker());
+ widgetMakers.add(new TestEmptyDom.Maker());
+ widgetMakers.add(new TestEmptyCursorDomCrawl.Maker());
+ widgetMakers.add(new TestEmptyRealisticDomCrawl.Maker());
+ widgetMakers.add(new TestDomViaApi.Maker());
+ widgetMakers.add(new TestDomInnerHtmlById.Maker());
+ if (Util.hasQSA) {
+ widgetMakers.add(new TestDomInnerHtmlQuerySelectorAll.Maker());
+ }
+ widgetMakers.add(new TestCursorDomCrawl.Maker());
+ widgetMakers.add(new TestRealisticDomCrawl.Maker());
+ widgetMakers.add(new TestDomBinder.Maker());
+ widgetMakers.add(new TestFlows.Maker());
+ widgetMakers.add(new TestManualHTMLPanel.Maker());
+ widgetMakers.add(new TestWidgetBinder.Maker());
+
+ // Add entries for new table benchmarks here.
+ List<Maker> tableMakers = new ArrayList<Maker>();
+ tableMakers.add(new TestCreateTableInnerHtml.Maker());
+ tableMakers.add(new TestCreateTablePrecreatedInnerHtml.Maker());
+ tableMakers.add(new TestCreateTableDom.Maker());
+ tableMakers.add(new TestCreateTableDomWithEvents.Maker());
+
+ benchmarks = new Microbenchmark[2];
+ benchmarks[0] = new WidgetCreation("Widget Creation Survey",
widgetMakers);
+ benchmarks[1] = new WidgetCreation("Table Creation Survey",
tableMakers);
+ }
+
@UiHandler("listBox")
public void onChange(@SuppressWarnings("unused") ChangeEvent ignored) {
int index = listBox.getSelectedIndex();
- deck.showWidget(index);
- }
-
+ deck.showWidget(index);
+ }
+
@UiHandler("button")
public void onClick(@SuppressWarnings("unused") ClickEvent ignored) {
final int index = listBox.getSelectedIndex();
@@ -79,7 +133,7 @@
}
});
}
-
+
public void onModuleLoad() {
Widget root = BINDER.createAndBindUi(this);
=======================================
---
/trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Util.java
Wed Jan 13 13:58:25 2010
+++
/trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/Util.java
Fri Apr 1 04:44:18 2011
@@ -24,7 +24,11 @@
+ "<span id='span2'></span>"
+ "</div>"
+ "</div>";
-
+
+ static final int TABLE_ROW_COUNT = 40;
+
+ static final int TABLE_COLUMN_COUNT = 10;
+
static final String TEXTY_OUTER_HTML = "<div>" + Util.TEXTY_INNER_HTML
+ "</div>";
static final String TEXTY_INNER_HTML = "Div root start"
@@ -43,7 +47,27 @@
static void addText(Element elm, String text) {
elm.appendChild(Document.get().createTextNode(text));
}
-
+
+ static String createTableHtml() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("<table>");
+ for (int row = 0; row < Util.TABLE_ROW_COUNT; row++) {
+ if (row % 2 == 0) {
+ sb.append("<tr class=\"evenRow\">");
+ } else {
+ sb.append("<tr class=\"oddRow\">");
+ }
+ for (int column = 0; column < Util.TABLE_COLUMN_COUNT; column++) {
+ sb.append("<td align=\"center\" valign=\"middle\"><div>");
+ sb.append("Cell " + row + ":" + column);
+ sb.append("</div></td>");
+ }
+ sb.append("</tr>");
+ }
+ sb.append("</table>");
+ return sb.toString();
+ }
+
static String format(double median) {
return NumberFormat.getFormat("0").format(median);
}
=======================================
---
/trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/WidgetCreation.java
Wed Jan 13 13:58:25 2010
+++
/trunk/reference/Microbenchmarks/src/com/google/gwt/reference/microbenchmark/client/WidgetCreation.java
Fri Apr 1 04:44:18 2011
@@ -16,23 +16,24 @@
package com.google.gwt.reference.microbenchmark.client;
import com.google.gwt.core.client.Duration;
+import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
+import com.google.gwt.uibinder.client.UiBinder;
+import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.Window.ClosingEvent;
import com.google.gwt.user.client.Window.ClosingHandler;
+import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Grid;
-import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.RootPanel;
-import com.google.gwt.user.client.ui.SimplePanel;
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;
@@ -50,6 +51,10 @@
abstract Widget make();
}
+
+ interface Binder extends UiBinder<Widget, WidgetCreation> {}
+
+ private static final Binder BINDER = GWT.create(Binder.class);
private static final String COOKIE = "gwt_microb_widgetCreation";
@@ -57,79 +62,41 @@
public static native void log(String msg) /*-{
var logger = $wnd.console;
- if(logger && logger.markTimeline) {
- logger.markTimeline(msg);
+ if (logger) {
+ logger.log(msg);
+ if(logger.markTimeline) {
+ logger.markTimeline(msg);
+ }
}
}-*/;
- final Grid grid;
-
- final TextBox number;
+ @UiField(provided = true) Grid grid;
+ @UiField CheckBox includeLargeWidget;
+ @UiField TextBox number;
+ @UiField Widget root;
+ final String name;
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;
-
- public WidgetCreation() {
+
+ /**
+ * Construct a new {@link WidgetCreation} micro benchmark.
+ *
+ * @param name the name of the benchmark
+ * @param makers the makers for the widget strategies
+ */
+ public WidgetCreation(String name, List<Maker> makers) {
+ this.name = name;
+ this.makers = Collections.unmodifiableList(makers);
+
int instances = DEFAULT_INSTANCES;
try {
instances = Integer.parseInt(Cookies.getCookie(COOKIE));
} catch (NumberFormatException ignored) {
}
- number = new TextBox();
- number.setVisibleLength(7);
- number.setValue("" + instances);
- number.addBlurHandler(new BlurHandler() {
- public void onBlur(BlurEvent event) {
- saveInstances();
- }
- });
-
- Window.addWindowClosingHandler(new ClosingHandler() {
- public void onWindowClosing(ClosingEvent event) {
- saveInstances();
- }
- });
-
+ // Initialize the grid.
grid = new Grid(makers.size() + 2, 3);
- grid.setText(0, 0, "50%");
- grid.setText(0, 1, "m");
+ grid.setText(0, 0, "median");
+ grid.setText(0, 1, "mean");
int row = 1;
for (Maker m : makers) {
@@ -141,18 +108,26 @@
grid.setWidget(row, 2, a);
row++;
}
-
- root = new FlowPanel();
- HTMLPanel l = new HTMLPanel(
- "<b>Time for creating, attaching and detaching "
- + "<span id='number'></span> instances, in MS<br><br></b>");
- l.addAndReplaceElement(number, "number");
- root.add(l);
- root.add(grid);
+
+ // Create the widget.
+ root = BINDER.createAndBindUi(this);
+ number.setVisibleLength(7);
+ number.setValue("" + instances);
+ number.addBlurHandler(new BlurHandler() {
+ public void onBlur(BlurEvent event) {
+ saveInstances();
+ }
+ });
+
+ Window.addWindowClosingHandler(new ClosingHandler() {
+ public void onWindowClosing(ClosingEvent event) {
+ saveInstances();
+ }
+ });
}
public String getName() {
- return "Widget Creation Survey";
+ return name;
}
public Widget getWidget() {
@@ -162,41 +137,70 @@
public void run() {
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();
- root.add(widgets[i]);
- }
-
- /*
- * Force a layout by finding the body's offsetTop. We avoid doing
- * setTimeout(0), which would allow paint to happen, to keep the test
- * synchronous and because different browsers round that zero to
different
- * minimums. Layout should be the bulk of the time.
- */
- Document.get().getBody().getOffsetTop();
-
- 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) {
- root.remove(widgets[i]);
- }
- row++;
- }
- grid.setText(row, grid.getColumnCount() - 1, Util.format(allTimes));
+ // Add a large widget to the root to reflect a typical application.
+ FlowPanel largeWidget = null;
+ if (includeLargeWidget.getValue()) {
+ largeWidget = new FlowPanel();
+ TestWidgetBinder.Maker widgetMaker = new TestWidgetBinder.Maker();
+ for (int i = 0; i < 100; i++) {
+ largeWidget.add(widgetMaker.make());
+ }
+ root.add(largeWidget);
+ }
+
+ int makersCount = makers.size();
+ double[] times = new double[makersCount];
+
+ int column = grid.getColumnCount();
+ grid.resizeColumns(column + 1);
+ grid.setText(0, column, "Run " + (column - 3));
+
+ final int instances = getInstances();
+ boolean forward = false;
+ for (int i = 0; i < instances; ++i) {
+ forward = !forward;
+ for (int m = 0; m < makersCount; m++) {
+ /*
+ * Alternate the order that we invoke the makers to cancel out the
+ * performance impact of adding elements to the DOM, which would
cause
+ * later tests to run more slowly than earlier tests.
+ */
+ Maker maker = makers.get(forward ? m : (makersCount - 1 - m));
+ log(i + ": " + maker.name);
+ double start = Duration.currentTimeMillis();
+ Widget w = maker.make();
+ root.add(w);
+
+ /*
+ * Force a layout by finding the body's offsetTop and height. We
avoid
+ * doing setTimeout(0), which would allow paint to happen, to keep
the
+ * test synchronous and because different browsers round that zero
to
+ * different minimums. Layout should be the bulk of the time.
+ */
+ Document.get().getBody().getOffsetTop();
+ Document.get().getBody().getOffsetHeight();
+ w.getOffsetHeight();
+
+ double thisTime = Duration.currentTimeMillis() - start;
+ times[m] += thisTime;
+
+ // Clean up to keep the dom. Attached widgets will affect later
tests.
+ root.remove(w);
+ }
+ }
+
+ // Record the times.
+ double allTimes = 0;
+ for (int m = 0; m < makersCount; ++m) {
+ record(m + 1, times[m]);
+ allTimes += times[m];
+ }
+ grid.setText(grid.getRowCount() - 1, grid.getColumnCount() - 1,
Util.format(allTimes));
+
+ // Cleanup the dom.
+ if (largeWidget != null) {
+ root.remove(largeWidget);
+ }
}
private int getInstances() {
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors