Procházet zdrojové kódy

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
tags/7.1.0
Fabian Lange před 11 roky
rodič
revize
5f66766f02

+ 10
- 12
server/src/com/vaadin/ui/AbstractComponent.java Zobrazit soubor

@@ -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());
}
}
}

+ 52
- 0
server/tests/src/com/vaadin/benchmarks/PerformanceTester8759.java Zobrazit soubor

@@ -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");
}
}

}

Načítá se…
Zrušit
Uložit