summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorFabian Lange <lange.fabian@gmail.com>2013-06-10 11:12:20 +0200
committerVaadin Code Review <review@vaadin.com>2013-06-12 13:37:52 +0000
commit5f66766f02b86aeda0089b8bb15da5b2c6e40715 (patch)
tree000109b5d6c2c9ffdbc01d9866ae6abb19f323c3 /server
parenteb64fda3eb8e04e9dd5ac014981d6e7cc9683b44 (diff)
downloadvaadin-framework-5f66766f02b86aeda0089b8bb15da5b2c6e40715.tar.gz
vaadin-framework-5f66766f02b86aeda0089b8bb15da5b2c6e40715.zip
Using StringTokenizer instead of String.split() in AbstractComponent (#8759)
Avoids wasteful creation and parsing of regular expressions, which are not required here. Change-Id: I247088fbfc4eca6c2500bd6b4da9afc9d66d0a51
Diffstat (limited to 'server')
-rw-r--r--server/src/com/vaadin/ui/AbstractComponent.java22
-rw-r--r--server/tests/src/com/vaadin/benchmarks/PerformanceTester8759.java52
2 files changed, 62 insertions, 12 deletions
diff --git a/server/src/com/vaadin/ui/AbstractComponent.java b/server/src/com/vaadin/ui/AbstractComponent.java
index 772a26bda2..262d47af18 100644
--- a/server/src/com/vaadin/ui/AbstractComponent.java
+++ b/server/src/com/vaadin/ui/AbstractComponent.java
@@ -22,6 +22,7 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
+import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -176,11 +177,9 @@ public abstract class AbstractComponent extends AbstractClientConnector
}
List<String> styles = getState().styles;
styles.clear();
- String[] styleParts = style.split(" +");
- for (String part : styleParts) {
- if (part.length() > 0) {
- styles.add(part);
- }
+ StringTokenizer tokenizer = new StringTokenizer(style, " ");
+ while (tokenizer.hasMoreTokens()) {
+ styles.add(tokenizer.nextToken());
}
}
@@ -201,8 +200,9 @@ public abstract class AbstractComponent extends AbstractClientConnector
}
if (style.contains(" ")) {
// Split space separated style names and add them one by one.
- for (String realStyle : style.split(" ")) {
- addStyleName(realStyle);
+ StringTokenizer tokenizer = new StringTokenizer(style, " ");
+ while (tokenizer.hasMoreTokens()) {
+ addStyleName(tokenizer.nextToken());
}
return;
}
@@ -219,11 +219,9 @@ public abstract class AbstractComponent extends AbstractClientConnector
@Override
public void removeStyleName(String style) {
if (ComponentStateUtil.hasStyles(getState())) {
- String[] styleParts = style.split(" +");
- for (String part : styleParts) {
- if (part.length() > 0) {
- getState().styles.remove(part);
- }
+ StringTokenizer tokenizer = new StringTokenizer(style, " ");
+ while (tokenizer.hasMoreTokens()) {
+ getState().styles.remove(tokenizer.nextToken());
}
}
}
diff --git a/server/tests/src/com/vaadin/benchmarks/PerformanceTester8759.java b/server/tests/src/com/vaadin/benchmarks/PerformanceTester8759.java
new file mode 100644
index 0000000000..968edd4b24
--- /dev/null
+++ b/server/tests/src/com/vaadin/benchmarks/PerformanceTester8759.java
@@ -0,0 +1,52 @@
+package com.vaadin.benchmarks;
+
+import com.vaadin.ui.Label;
+
+/*
+ * This simple test shows the performance difference between the StringTokenizer implementation and the String.split() implementation in AbstractComponent.
+ * Your results will vary.
+ * The real world use case motivating it was a 10k Row table, which generated labels for 10 columns.
+ * This is 1/10th of what this performance tester demonstrates.
+ *
+ * Please run with -server and -Xloggc:/tmp/gclog.vgc -verbose:gc -XX:+PrintCompilation
+ *
+ * My results Win 7 64, i7 2760QM 2.4Ghz, Java 7 21.
+ *
+ * Proposed Patch with StringTokenizer:
+ * 13 GC activations, 1.009GB allocated memory over time, total time 948ms
+ *
+ * Current String.split implementation:
+ * 31 GC activations, 2.277 GB allocated memory over time, total time 1557ms
+ *
+ */
+public class PerformanceTester8759 {
+
+ public static void main(String[] args) throws InterruptedException {
+ warmup();
+
+ long start = System.currentTimeMillis();
+ runBenchmark(1000000);
+ long end = System.currentTimeMillis();
+ System.out.println("took " + (end - start) + " ms");
+
+ }
+
+ private static void warmup() throws InterruptedException {
+ runBenchmark(10000);
+ System.gc();
+ System.out.println("warmup and gc complete. sleeping 5 seconds.");
+ Thread.sleep(5000l);
+ System.out.println("woke up - go.");
+ }
+
+ private static void runBenchmark(int loops) {
+ Label label = null;
+ for (int i = 0; i < loops; i++) {
+ label = new Label();
+ label.setStyleName("mainStyle");
+ label.addStyleName("foo bar baz");
+ label.addStyleName("vaadin");
+ }
+ }
+
+}