Skip to content

Instantly share code, notes, and snippets.

@vlsi
Created February 4, 2017 17:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vlsi/63a1d4732f027ce70229af830ce20648 to your computer and use it in GitHub Desktop.
Save vlsi/63a1d4732f027ce70229af830ce20648 to your computer and use it in GitHub Desktop.
JTextArea append benchmark

According to the measurements, replaceRange + append works faster than setText except for the case when text is fully replaced. In 100% replace case setText is on par with replaceRange + append (the results are within error bounds).

For small appends there's a win in terms of response time and memory allocation.

# JMH 1.12 (released 309 days ago, please consider updating!)
# VM version: JDK 1.8.0_102, VM 25.102-b14
# VM invoker: /Library/Java/JavaVirtualMachines/jdk1.8.0_102.jdk/Contents/Home/jre/bin/java
Benchmark                                                           (maxLength)  Mode  Cnt        Score        Error   Units
TextAreaBenchmark.append100pct                                           100000  avgt    5        0,558 ±      0,142   ms/op
TextAreaBenchmark.append100pct:·gc.alloc.rate.norm                       100000  avgt    5  1644296,258 ±      0,067    B/op
TextAreaBenchmark.append50pct                                            100000  avgt    5        0,466 ±      0,070   ms/op
TextAreaBenchmark.append50pct:·gc.alloc.rate.norm                        100000  avgt    5   922424,215 ±      0,032    B/op
TextAreaBenchmark.append_1line                                           100000  avgt    5        0,394 ±      0,031   ms/op
TextAreaBenchmark.append_1line:·gc.alloc.rate.norm                       100000  avgt    5   201824,182 ±      0,014    B/op
TextAreaBenchmark.append_2lines                                          100000  avgt    5        0,374 ±      0,019   ms/op
TextAreaBenchmark.append_2lines:·gc.alloc.rate.norm                      100000  avgt    5   203912,173 ±      0,009    B/op
TextAreaBenchmark.baseline_getLog                                        100000  avgt    5        0,101 ±      0,014   ms/op
TextAreaBenchmark.baseline_getLog:·gc.alloc.rate.norm                    100000  avgt    5   777672,047 ±      0,007    B/op
TextAreaBenchmark.setText                                                100000  avgt    5        0,539 ±      0,046   ms/op
TextAreaBenchmark.setText:·gc.alloc.rate.norm                            100000  avgt    5  1578840,249 ±      0,021    B/op
package com.github.vlsi.benchmarks;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.profile.GCProfiler;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.concurrent.TimeUnit;
import javax.swing.*;
@Fork(1)
@Measurement(iterations = 5)
@Warmup(iterations = 5)
@State(Scope.Thread)
@Threads(1)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class TextAreaBenchmark {
// Log generation is not included into "textarea benchmark". It is assumed log formatting is done outside of the UI thread
private String logLine =
System.currentTimeMillis()
+ " test test test sadf lkashdf;laksjdf ;lkasdjf ;lkasjdf ;laksjdf;l kasdjflkjsdfkjsdklfajsdlkfjhalsdkjfhalskdj fhalsdk jfhalksdj";
@Param({"100000"})
int maxLength = 100000;
int linesTotal;
JTextArea area = new JTextArea();
@Setup
public void setup() {
String log = baseline_getLog();
area.setText(log);
linesTotal = log.length() / getLogLine().length();
System.out.println("linesTotal = " + linesTotal);
}
public String getLogLine() {
return logLine;
}
@Benchmark
public String baseline_getLog() {
StringBuilder sb = new StringBuilder();
while (sb.length() < maxLength) {
sb.append(getLogLine());
}
return sb.toString();
}
@Benchmark
public void setText() {
area.setText(baseline_getLog());
}
@Benchmark
public void append_1line() {
append(1);
}
@Benchmark
public void append_2lines() {
append(2);
}
@Benchmark
public void append50pct() {
append(linesTotal / 2);
}
@Benchmark
public void append100pct() {
append(linesTotal);
}
public void append(int n) {
String logLine = getLogLine();
area.replaceRange("", 0, logLine.length() * n);
StringBuilder sb = new StringBuilder(logLine);
for (int i = 1; i < n; i++) {
sb.append(getLogLine());
}
area.append(sb.toString());
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(TextAreaBenchmark.class.getSimpleName())
.addProfiler(GCProfiler.class)
.detectJvmArgs()
.build();
new Runner(opt).run();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment