Skip to content

📈 Benchmark 004: Concatenating Strings ​

📘 Preface ​

String concatenation in Java isn't always handled the same way. While the + operator appears simple, repeated use in loops can result in poor performance due to object churn.

🔬 Test Case ​

java
@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
@Fork(1)
@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
public class BM_004_StringConcatenation {

  @Param({"1", "10", "100"})
  private int length;

  private String[] strings;

  @Setup
  public void setup() {
    var strings = new String[length];
    for (int i = 0; i < length; i++) {
      strings[i] = "str" + i;
    }
    this.strings = strings;
  }

  @Benchmark
  public void plus(Blackhole bh) {
    var result = "";
    for (var str : this.strings) {
      result = result + str;
    }
    bh.consume(result);
  }

  @Benchmark
  public void concat(Blackhole bh) {
    var result = "";
    for (var str : this.strings) {
      result = result.concat(str);
    }
    bh.consume(result);
  }

  @Benchmark
  public void builder(Blackhole bh) {
    var sb = new StringBuilder();
    for (var str : this.strings) {
      sb.append(str);
    }
    bh.consume(sb.toString());
  }

  @Benchmark
  public void join(Blackhole bh) {
    bh.consume(String.join("", strings));
  }
}

✅ Results ​

Benchmark                           (length)  Mode  Cnt     Score    Error  Units
BM_004_StringConcatenation.builder         1  avgt    5    17.485 ±  0.309  ns/op
BM_004_StringConcatenation.builder        10  avgt    5    87.555 ±  1.302  ns/op
BM_004_StringConcatenation.builder       100  avgt    5   737.058 ± 53.362  ns/op
BM_004_StringConcatenation.concat          1  avgt    5    12.890 ±  0.132  ns/op
BM_004_StringConcatenation.concat         10  avgt    5   149.736 ±  0.545  ns/op
BM_004_StringConcatenation.concat        100  avgt    5  2208.537 ± 48.658  ns/op
BM_004_StringConcatenation.join            1  avgt    5    14.247 ±  0.151  ns/op
BM_004_StringConcatenation.join           10  avgt    5    98.986 ±  1.144  ns/op
BM_004_StringConcatenation.join          100  avgt    5   979.874 ± 40.951  ns/op
BM_004_StringConcatenation.plus            1  avgt    5     3.747 ±  0.052  ns/op
BM_004_StringConcatenation.plus           10  avgt    5   148.860 ±  2.753  ns/op
BM_004_StringConcatenation.plus          100  avgt    5  2240.235 ± 98.413  ns/op

🔎 Findings ​

Traditionally, StringBuilders are thought to be the fastest, even internally Java compiles some + concatenations down to using StringBuilders, but String.join() actually starts to out perform as lambda/stream performances gets better and better within Java itself after Java 8, though we can only observe this as the strings become longer and longer.