Runtime comparison of string concatenation

One of the mostly asked questions is “How should I do string concatenation?”. And the answer to this question is not very straight forward.  Here I would benchmark the three string concatenation operations.

Tools Used

I am using jmh to do the benchmarking. And used maven to run the benchmark code  on java 8 as recommended in jmh documentation.

Benchmark String concatenation in  a loop

In this example I have done string concatenation within a loop. And lets see how the output turns out.


package com.programtalk.java8.tutorial;

import java.util.concurrent.TimeUnit;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;

@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Fork(value = 3, jvmArgsAppend = { "-server", "-disablesystemassertions" })
public class ConcatenationComparision {

	@Benchmark
	@Warmup(iterations = 10, time = 3, timeUnit = TimeUnit.SECONDS)
	public String stringBuilderConcatenate() {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; < 100000; i++) {
			sb.append("string");
		}
		return sb.toString();
	}

	@Benchmark
	@Warmup(iterations = 10, time = 3, timeUnit = TimeUnit.SECONDS)
	public String stringBufferConcatenate() {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < 100000; i++) {
			sb.append("string");
		}
		return sb.toString();
	}

	@Benchmark
	@Warmup(iterations = 10, time = 3, timeUnit = TimeUnit.SECONDS)
	public String concatenatePlusEquals() {
		String st = "hello";
		for (int i = 0; i < 100000; i++) {
			st += "string";
		}
		return st;
	}
}

Overview of the results


Benchmark                                         Mode Cnt Score      Error     Units
ConcatenationComparision.concatenatePlusEquals    avgt 60  11572.325  ± 104.951 ms/op
ConcatenationComparision.stringBufferConcatenate  avgt 60  1.471      ± 0.035   ms/op
ConcatenationComparision.stringBuilderConcatenate avgt 60  1.525      ± 0.020   ms/op

So if we see the results above concatenatePlusEquals is the worst performer with 11572.325 milliseconds/operation  and the other two operation take 0.035 ms/op and 0.020 ms/op. This means that “+=” operator is 11000 times less efficent than StringBuffer and StringBuilder. But don’t make up your minds now as the next example will have equally exciting results.

Full log

# JMH 1.12 (released 18 days ago)
# VM version: JDK 1.8.0_77, VM 25.77-b03
# VM invoker: C:\Program Files\Java\jre1.8.0_77\bin\java.exe
# VM options: -server -disablesystemassertions
# Warmup: 10 iterations, 3 s each
# Measurement: 20 iterations, 1 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Average time, time/op
# Benchmark: com.programtalk.java8.tutorial.ConcatenationComparision.concatenatePlusEquals

# Run progress: 0.00% complete, ETA 00:07:30
# Fork: 1 of 3
# Warmup Iteration 1: 29026.249 ms/op
# Warmup Iteration 2: 11515.075 ms/op
# Warmup Iteration 3: 11625.230 ms/op
# Warmup Iteration 4: 11265.016 ms/op
# Warmup Iteration 5: 12201.576 ms/op
# Warmup Iteration 6: 11502.628 ms/op
# Warmup Iteration 7: 11404.251 ms/op
# Warmup Iteration 8: 11782.064 ms/op
# Warmup Iteration 9: 11176.152 ms/op
# Warmup Iteration 10: 11012.261 ms/op
Iteration 1: 11663.784 ms/op
Iteration 2: 12123.228 ms/op
Iteration 3: 11936.755 ms/op
Iteration 4: 11827.529 ms/op
Iteration 5: 11244.712 ms/op
Iteration 6: 11809.777 ms/op
Iteration 7: 12027.728 ms/op
Iteration 8: 12152.749 ms/op
Iteration 9: 11260.366 ms/op
Iteration 10: 11470.332 ms/op
Iteration 11: 11632.911 ms/op
Iteration 12: 11460.662 ms/op
Iteration 13: 11746.295 ms/op
Iteration 14: 11453.243 ms/op
Iteration 15: 11355.766 ms/op
Iteration 16: 11051.642 ms/op
Iteration 17: 11502.569 ms/op
Iteration 18: 11686.925 ms/op
Iteration 19: 11513.996 ms/op
Iteration 20: 11755.533 ms/op

# Run progress: 11.11% complete, ETA 00:48:45
# Fork: 2 of 3
# Warmup Iteration 1: 31015.111 ms/op
# Warmup Iteration 2: 11847.680 ms/op
# Warmup Iteration 3: 11187.849 ms/op
# Warmup Iteration 4: 11712.085 ms/op
# Warmup Iteration 5: 11746.606 ms/op
# Warmup Iteration 6: 11683.458 ms/op
# Warmup Iteration 7: 12043.231 ms/op
# Warmup Iteration 8: 12126.888 ms/op
# Warmup Iteration 9: 11803.950 ms/op
# Warmup Iteration 10: 11565.470 ms/op
Iteration 1: 11902.147 ms/op
Iteration 2: 11516.863 ms/op
Iteration 3: 11518.939 ms/op
Iteration 4: 11511.284 ms/op
Iteration 5: 11295.020 ms/op
Iteration 6: 11677.118 ms/op
Iteration 7: 11619.642 ms/op
Iteration 8: 11964.386 ms/op
Iteration 9: 11642.745 ms/op
Iteration 10: 11717.145 ms/op
Iteration 11: 11452.303 ms/op
Iteration 12: 11482.042 ms/op
Iteration 13: 11581.110 ms/op
Iteration 14: 11654.061 ms/op
Iteration 15: 11264.541 ms/op
Iteration 16: 11243.485 ms/op
Iteration 17: 11383.994 ms/op
Iteration 18: 11506.032 ms/op
Iteration 19: 11446.045 ms/op
Iteration 20: 11403.822 ms/op

# Run progress: 22.22% complete, ETA 00:42:47
# Fork: 3 of 3
# Warmup Iteration 1: 28695.977 ms/op
# Warmup Iteration 2: 11444.238 ms/op
# Warmup Iteration 3: 11664.799 ms/op
# Warmup Iteration 4: 11655.362 ms/op
# Warmup Iteration 5: 11561.321 ms/op
# Warmup Iteration 6: 11466.525 ms/op
# Warmup Iteration 7: 11413.860 ms/op
# Warmup Iteration 8: 11446.732 ms/op
# Warmup Iteration 9: 11537.595 ms/op
# Warmup Iteration 10: 11347.037 ms/op
Iteration 1: 11384.033 ms/op
Iteration 2: 11460.320 ms/op
Iteration 3: 11628.296 ms/op
Iteration 4: 11905.415 ms/op
Iteration 5: 11807.408 ms/op
Iteration 6: 11305.356 ms/op
Iteration 7: 11592.860 ms/op
Iteration 8: 11490.144 ms/op
Iteration 9: 11464.824 ms/op
Iteration 10: 11637.315 ms/op
Iteration 11: 11398.794 ms/op
Iteration 12: 11649.445 ms/op
Iteration 13: 12041.672 ms/op
Iteration 14: 11541.617 ms/op
Iteration 15: 11493.807 ms/op
Iteration 16: 11270.454 ms/op
Iteration 17: 11338.346 ms/op
Iteration 18: 11419.955 ms/op
Iteration 19: 11664.406 ms/op
Iteration 20: 11385.820 ms/op


Result "concatenatePlusEquals":
 11572.325 ±(99.9%) 104.951 ms/op [Average]
 (min, avg, max) = (11051.642, 11572.325, 12152.749), stdev = 234.739
 CI (99.9%): [11467.374, 11677.277] (assumes normal distribution)


# JMH 1.12 (released 18 days ago)
# VM version: JDK 1.8.0_77, VM 25.77-b03
# VM invoker: C:\Program Files\Java\jre1.8.0_77\bin\java.exe
# VM options: -server -disablesystemassertions
# Warmup: 10 iterations, 3 s each
# Measurement: 20 iterations, 1 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Average time, time/op
# Benchmark: com.programtalk.java8.tutorial.ConcatenationComparision.stringBufferConcatenate

# Run progress: 33.33% complete, ETA 00:36:34
# Fork: 1 of 3
# Warmup Iteration 1: 1.636 ms/op
# Warmup Iteration 2: 1.406 ms/op
# Warmup Iteration 3: 1.431 ms/op
# Warmup Iteration 4: 1.455 ms/op
# Warmup Iteration 5: 1.468 ms/op
# Warmup Iteration 6: 1.437 ms/op
# Warmup Iteration 7: 1.516 ms/op
# Warmup Iteration 8: 1.409 ms/op
# Warmup Iteration 9: 1.420 ms/op
# Warmup Iteration 10: 1.438 ms/op
Iteration 1: 1.520 ms/op
Iteration 2: 1.435 ms/op
Iteration 3: 1.402 ms/op
Iteration 4: 1.511 ms/op
Iteration 5: 1.405 ms/op
Iteration 6: 1.413 ms/op
Iteration 7: 1.451 ms/op
Iteration 8: 1.437 ms/op
Iteration 9: 1.432 ms/op
Iteration 10: 1.443 ms/op
Iteration 11: 1.415 ms/op
Iteration 12: 1.408 ms/op
Iteration 13: 1.431 ms/op
Iteration 14: 1.431 ms/op
Iteration 15: 1.427 ms/op
Iteration 16: 1.467 ms/op
Iteration 17: 1.407 ms/op
Iteration 18: 1.401 ms/op
Iteration 19: 1.406 ms/op
Iteration 20: 1.402 ms/op

# Run progress: 44.44% complete, ETA 00:23:54
# Fork: 2 of 3
# Warmup Iteration 1: 1.625 ms/op
# Warmup Iteration 2: 1.413 ms/op
# Warmup Iteration 3: 1.464 ms/op
# Warmup Iteration 4: 1.414 ms/op
# Warmup Iteration 5: 1.430 ms/op
# Warmup Iteration 6: 1.423 ms/op
# Warmup Iteration 7: 1.427 ms/op
# Warmup Iteration 8: 1.443 ms/op
# Warmup Iteration 9: 1.415 ms/op
# Warmup Iteration 10: 1.426 ms/op
Iteration 1: 1.444 ms/op
Iteration 2: 1.466 ms/op
Iteration 3: 1.447 ms/op
Iteration 4: 1.412 ms/op
Iteration 5: 1.442 ms/op
Iteration 6: 1.457 ms/op
Iteration 7: 1.462 ms/op
Iteration 8: 1.413 ms/op
Iteration 9: 1.438 ms/op
Iteration 10: 1.427 ms/op
Iteration 11: 1.430 ms/op
Iteration 12: 1.499 ms/op
Iteration 13: 1.606 ms/op
Iteration 14: 1.453 ms/op
Iteration 15: 1.433 ms/op
Iteration 16: 1.410 ms/op
Iteration 17: 1.436 ms/op
Iteration 18: 1.426 ms/op
Iteration 19: 1.520 ms/op
Iteration 20: 1.496 ms/op

# Run progress: 55.56% complete, ETA 00:15:58
# Fork: 3 of 3
# Warmup Iteration 1: 1.720 ms/op
# Warmup Iteration 2: 1.507 ms/op
# Warmup Iteration 3: 1.457 ms/op
# Warmup Iteration 4: 1.457 ms/op
# Warmup Iteration 5: 1.443 ms/op
# Warmup Iteration 6: 1.507 ms/op
# Warmup Iteration 7: 1.584 ms/op
# Warmup Iteration 8: 1.901 ms/op
# Warmup Iteration 9: 1.701 ms/op
# Warmup Iteration 10: 2.060 ms/op
Iteration 1: 1.866 ms/op
Iteration 2: 1.684 ms/op
Iteration 3: 1.490 ms/op
Iteration 4: 1.636 ms/op
Iteration 5: 1.507 ms/op
Iteration 6: 1.450 ms/op
Iteration 7: 1.466 ms/op
Iteration 8: 1.443 ms/op
Iteration 9: 1.481 ms/op
Iteration 10: 1.448 ms/op
Iteration 11: 1.500 ms/op
Iteration 12: 1.609 ms/op
Iteration 13: 1.545 ms/op
Iteration 14: 1.469 ms/op
Iteration 15: 1.522 ms/op
Iteration 16: 1.488 ms/op
Iteration 17: 1.443 ms/op
Iteration 18: 1.471 ms/op
Iteration 19: 1.492 ms/op
Iteration 20: 1.502 ms/op


Result "stringBufferConcatenate":
 1.471 ±(99.9%) 0.035 ms/op [Average]
 (min, avg, max) = (1.401, 1.471, 1.866), stdev = 0.078
 CI (99.9%): [1.436, 1.506] (assumes normal distribution)


# JMH 1.12 (released 18 days ago)
# VM version: JDK 1.8.0_77, VM 25.77-b03
# VM invoker: C:\Program Files\Java\jre1.8.0_77\bin\java.exe
# VM options: -server -disablesystemassertions
# Warmup: 10 iterations, 3 s each
# Measurement: 20 iterations, 1 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Average time, time/op
# Benchmark: com.programtalk.java8.tutorial.ConcatenationComparision.stringBuilderConcatenate

# Run progress: 66.67% complete, ETA 00:10:24
# Fork: 1 of 3
# Warmup Iteration 1: 1.663 ms/op
# Warmup Iteration 2: 1.484 ms/op
# Warmup Iteration 3: 1.528 ms/op
# Warmup Iteration 4: 1.482 ms/op
# Warmup Iteration 5: 1.476 ms/op
# Warmup Iteration 6: 1.533 ms/op
# Warmup Iteration 7: 1.533 ms/op
# Warmup Iteration 8: 1.591 ms/op
# Warmup Iteration 9: 1.748 ms/op
# Warmup Iteration 10: 1.481 ms/op
Iteration 1: 1.479 ms/op
Iteration 2: 1.467 ms/op
Iteration 3: 1.500 ms/op
Iteration 4: 1.552 ms/op
Iteration 5: 1.502 ms/op
Iteration 6: 1.509 ms/op
Iteration 7: 1.502 ms/op
Iteration 8: 1.604 ms/op
Iteration 9: 1.685 ms/op
Iteration 10: 1.639 ms/op
Iteration 11: 1.523 ms/op
Iteration 12: 1.503 ms/op
Iteration 13: 1.580 ms/op
Iteration 14: 1.560 ms/op
Iteration 15: 1.681 ms/op
Iteration 16: 1.479 ms/op
Iteration 17: 1.524 ms/op
Iteration 18: 1.486 ms/op
Iteration 19: 1.503 ms/op
Iteration 20: 1.487 ms/op

# Run progress: 77.78% complete, ETA 00:06:11
# Fork: 2 of 3
# Warmup Iteration 1: 1.665 ms/op
# Warmup Iteration 2: 1.545 ms/op
# Warmup Iteration 3: 1.525 ms/op
# Warmup Iteration 4: 1.566 ms/op
# Warmup Iteration 5: 1.545 ms/op
# Warmup Iteration 6: 1.538 ms/op
# Warmup Iteration 7: 1.514 ms/op
# Warmup Iteration 8: 1.550 ms/op
# Warmup Iteration 9: 1.538 ms/op
# Warmup Iteration 10: 1.533 ms/op
Iteration 1: 1.517 ms/op
Iteration 2: 1.543 ms/op
Iteration 3: 1.510 ms/op
Iteration 4: 1.549 ms/op
Iteration 5: 1.540 ms/op
Iteration 6: 1.522 ms/op
Iteration 7: 1.513 ms/op
Iteration 8: 1.601 ms/op
Iteration 9: 1.521 ms/op
Iteration 10: 1.501 ms/op
Iteration 11: 1.522 ms/op
Iteration 12: 1.516 ms/op
Iteration 13: 1.524 ms/op
Iteration 14: 1.543 ms/op
Iteration 15: 1.569 ms/op
Iteration 16: 1.565 ms/op
Iteration 17: 1.516 ms/op
Iteration 18: 1.545 ms/op
Iteration 19: 1.563 ms/op
Iteration 20: 1.520 ms/op

# Run progress: 88.89% complete, ETA 00:02:48
# Fork: 3 of 3
# Warmup Iteration 1: 1.647 ms/op
# Warmup Iteration 2: 1.495 ms/op
# Warmup Iteration 3: 1.494 ms/op
# Warmup Iteration 4: 1.514 ms/op
# Warmup Iteration 5: 1.497 ms/op
# Warmup Iteration 6: 1.499 ms/op
# Warmup Iteration 7: 1.537 ms/op
# Warmup Iteration 8: 1.498 ms/op
# Warmup Iteration 9: 1.492 ms/op
# Warmup Iteration 10: 1.509 ms/op
Iteration 1: 1.502 ms/op
Iteration 2: 1.522 ms/op
Iteration 3: 1.539 ms/op
Iteration 4: 1.505 ms/op
Iteration 5: 1.498 ms/op
Iteration 6: 1.475 ms/op
Iteration 7: 1.544 ms/op
Iteration 8: 1.476 ms/op
Iteration 9: 1.483 ms/op
Iteration 10: 1.507 ms/op
Iteration 11: 1.478 ms/op
Iteration 12: 1.495 ms/op
Iteration 13: 1.500 ms/op
Iteration 14: 1.551 ms/op
Iteration 15: 1.489 ms/op
Iteration 16: 1.487 ms/op
Iteration 17: 1.542 ms/op
Iteration 18: 1.494 ms/op
Iteration 19: 1.491 ms/op
Iteration 20: 1.476 ms/op


Result "stringBuilderConcatenate":
 1.525 ±(99.9%) 0.020 ms/op [Average]
 (min, avg, max) = (1.467, 1.525, 1.685), stdev = 0.046
 CI (99.9%): [1.505, 1.546] (assumes normal distribution)


# Run complete. Total time: 00:23:20

Benchmark Mode Cnt Score Error Units
ConcatenationComparision.concatenatePlusEquals avgt 60 11572.325 ± 104.951 ms/op
ConcatenationComparision.stringBufferConcatenate avgt 60 1.471 ± 0.035 ms/op
ConcatenationComparision.stringBuilderConcatenate avgt 60 1.525 ± 0.020 ms/op

 

Benchmark String concatenation operation

Example Code

The difference here with the code above is that I have removed the loop and have also changed the the OutputTimeUnit to microseconds so as to get meaningful results.


package com.programtalk.java8.tutorial;

import java.util.concurrent.TimeUnit;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;

@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Fork(value = 3, jvmArgsAppend = { "-server", "-disablesystemassertions" })
public class ConcatenationComparision {

	@Benchmark
	@Warmup(iterations = 10, time = 3, timeUnit = TimeUnit.SECONDS)
	public String stringBuilderConcatenate() {
		StringBuilder sb = new StringBuilder("hello");
		sb.append("string");
		return sb.toString();
	}

	@Benchmark
	@Warmup(iterations = 10, time = 3, timeUnit = TimeUnit.SECONDS)
	public String stringBufferConcatenate() {
		StringBuffer sb = new StringBuffer("hello");
		sb.append("string");
		return sb.toString();
	}

	@Benchmark
	@Warmup(iterations = 10, time = 3, timeUnit = TimeUnit.SECONDS)
	public String concatenatePlusEquals() {
		String st = "hello";
		return st += "string";
	}
}

Overview of the results

Benchmark                                          Mode Cnt  Score  Error   Units
ConcatenationComparision.concatenatePlusEquals     avgt 60   0.012  ± 0.001 us/op
ConcatenationComparision.stringBufferConcatenate   avgt 60   0.026  ± 0.001 us/op
ConcatenationComparision.stringBuilderConcatenate  avgt 60   0.026  ± 0.001 us/op

Here the results are quite different from the concatenations in loop. concatenatePlusEquals seems to do better than the other two operations.

Full log


# JMH 1.12 (released 18 days ago)
# VM version: JDK 1.8.0_77, VM 25.77-b03
# VM invoker: C:\Program Files\Java\jre1.8.0_77\bin\java.exe
# VM options: -server -disablesystemassertions
# Warmup: 10 iterations, 3 s each
# Measurement: 20 iterations, 1 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Average time, time/op
# Benchmark: com.programtalk.java8.tutorial.ConcatenationComparision.concatenatePlusEquals

# Run progress: 0.00% complete, ETA 00:07:30
# Fork: 1 of 3
# Warmup Iteration 1: 0.014 us/op
# Warmup Iteration 2: 0.012 us/op
# Warmup Iteration 3: 0.012 us/op
# Warmup Iteration 4: 0.012 us/op
# Warmup Iteration 5: 0.012 us/op
# Warmup Iteration 6: 0.012 us/op
# Warmup Iteration 7: 0.012 us/op
# Warmup Iteration 8: 0.012 us/op
# Warmup Iteration 9: 0.012 us/op
# Warmup Iteration 10: 0.012 us/op
Iteration 1: 0.012 us/op
Iteration 2: 0.012 us/op
Iteration 3: 0.012 us/op
Iteration 4: 0.012 us/op
Iteration 5: 0.012 us/op
Iteration 6: 0.012 us/op
Iteration 7: 0.012 us/op
Iteration 8: 0.012 us/op
Iteration 9: 0.012 us/op
Iteration 10: 0.012 us/op
Iteration 11: 0.012 us/op
Iteration 12: 0.012 us/op
Iteration 13: 0.012 us/op
Iteration 14: 0.012 us/op
Iteration 15: 0.012 us/op
Iteration 16: 0.012 us/op
Iteration 17: 0.012 us/op
Iteration 18: 0.012 us/op
Iteration 19: 0.013 us/op
Iteration 20: 0.012 us/op

# Run progress: 11.11% complete, ETA 00:06:43
# Fork: 2 of 3
# Warmup Iteration 1: 0.014 us/op
# Warmup Iteration 2: 0.012 us/op
# Warmup Iteration 3: 0.012 us/op
# Warmup Iteration 4: 0.012 us/op
# Warmup Iteration 5: 0.012 us/op
# Warmup Iteration 6: 0.012 us/op
# Warmup Iteration 7: 0.012 us/op
# Warmup Iteration 8: 0.012 us/op
# Warmup Iteration 9: 0.012 us/op
# Warmup Iteration 10: 0.012 us/op
Iteration 1: 0.012 us/op
Iteration 2: 0.012 us/op
Iteration 3: 0.012 us/op
Iteration 4: 0.012 us/op
Iteration 5: 0.012 us/op
Iteration 6: 0.012 us/op
Iteration 7: 0.012 us/op
Iteration 8: 0.012 us/op
Iteration 9: 0.012 us/op
Iteration 10: 0.012 us/op
Iteration 11: 0.012 us/op
Iteration 12: 0.012 us/op
Iteration 13: 0.012 us/op
Iteration 14: 0.012 us/op
Iteration 15: 0.012 us/op
Iteration 16: 0.012 us/op
Iteration 17: 0.012 us/op
Iteration 18: 0.012 us/op
Iteration 19: 0.012 us/op
Iteration 20: 0.012 us/op

# Run progress: 22.22% complete, ETA 00:05:53
# Fork: 3 of 3
# Warmup Iteration 1: 0.014 us/op
# Warmup Iteration 2: 0.012 us/op
# Warmup Iteration 3: 0.012 us/op
# Warmup Iteration 4: 0.012 us/op
# Warmup Iteration 5: 0.012 us/op
# Warmup Iteration 6: 0.012 us/op
# Warmup Iteration 7: 0.012 us/op
# Warmup Iteration 8: 0.012 us/op
# Warmup Iteration 9: 0.012 us/op
# Warmup Iteration 10: 0.012 us/op
Iteration 1: 0.012 us/op
Iteration 2: 0.012 us/op
Iteration 3: 0.012 us/op
Iteration 4: 0.012 us/op
Iteration 5: 0.012 us/op
Iteration 6: 0.012 us/op
Iteration 7: 0.012 us/op
Iteration 8: 0.012 us/op
Iteration 9: 0.012 us/op
Iteration 10: 0.012 us/op
Iteration 11: 0.012 us/op
Iteration 12: 0.012 us/op
Iteration 13: 0.012 us/op
Iteration 14: 0.012 us/op
Iteration 15: 0.012 us/op
Iteration 16: 0.012 us/op
Iteration 17: 0.012 us/op
Iteration 18: 0.012 us/op
Iteration 19: 0.012 us/op
Iteration 20: 0.012 us/op
Result "concatenatePlusEquals":
0.012 ±(99.9%) 0.001 us/op [Average]
(min, avg, max) = (0.012, 0.012, 0.013), stdev = 0.001
CI (99.9%): [0.012, 0.012] (assumes normal distribution)
# JMH 1.12 (released 18 days ago)
# VM version: JDK 1.8.0_77, VM 25.77-b03
# VM invoker: C:\Program Files\Java\jre1.8.0_77\bin\java.exe
# VM options: -server -disablesystemassertions
# Warmup: 10 iterations, 3 s each
# Measurement: 20 iterations, 1 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Average time, time/op
# Benchmark: com.programtalk.java8.tutorial.ConcatenationComparision.stringBufferConcatenate

# Run progress: 33.33% complete, ETA 00:05:02
# Fork: 1 of 3
# Warmup Iteration 1: 0.030 us/op
# Warmup Iteration 2: 0.026 us/op
# Warmup Iteration 3: 0.026 us/op
# Warmup Iteration 4: 0.026 us/op
# Warmup Iteration 5: 0.026 us/op
# Warmup Iteration 6: 0.027 us/op
# Warmup Iteration 7: 0.026 us/op
# Warmup Iteration 8: 0.026 us/op
# Warmup Iteration 9: 0.027 us/op
# Warmup Iteration 10: 0.026 us/op
Iteration 1: 0.026 us/op
Iteration 2: 0.026 us/op
Iteration 3: 0.025 us/op
Iteration 4: 0.026 us/op
Iteration 5: 0.026 us/op
Iteration 6: 0.026 us/op
Iteration 7: 0.026 us/op
Iteration 8: 0.026 us/op
Iteration 9: 0.026 us/op
Iteration 10: 0.025 us/op
Iteration 11: 0.026 us/op
Iteration 12: 0.026 us/op
Iteration 13: 0.026 us/op
Iteration 14: 0.026 us/op
Iteration 15: 0.026 us/op
Iteration 16: 0.026 us/op
Iteration 17: 0.026 us/op
Iteration 18: 0.026 us/op
Iteration 19: 0.026 us/op
Iteration 20: 0.026 us/op

# Run progress: 44.44% complete, ETA 00:04:12
# Fork: 2 of 3
# Warmup Iteration 1: 0.030 us/op
# Warmup Iteration 2: 0.026 us/op
# Warmup Iteration 3: 0.026 us/op
# Warmup Iteration 4: 0.026 us/op
# Warmup Iteration 5: 0.026 us/op
# Warmup Iteration 6: 0.026 us/op
# Warmup Iteration 7: 0.026 us/op
# Warmup Iteration 8: 0.026 us/op
# Warmup Iteration 9: 0.026 us/op
# Warmup Iteration 10: 0.026 us/op
Iteration 1: 0.026 us/op
Iteration 2: 0.026 us/op
Iteration 3: 0.026 us/op
Iteration 4: 0.026 us/op
Iteration 5: 0.026 us/op
Iteration 6: 0.028 us/op
Iteration 7: 0.026 us/op
Iteration 8: 0.026 us/op
Iteration 9: 0.026 us/op
Iteration 10: 0.026 us/op
Iteration 11: 0.026 us/op
Iteration 12: 0.026 us/op
Iteration 13: 0.026 us/op
Iteration 14: 0.026 us/op
Iteration 15: 0.026 us/op
Iteration 16: 0.026 us/op
Iteration 17: 0.026 us/op
Iteration 18: 0.026 us/op
Iteration 19: 0.026 us/op
Iteration 20: 0.027 us/op

# Run progress: 55.56% complete, ETA 00:03:21
# Fork: 3 of 3
# Warmup Iteration 1: 0.030 us/op
# Warmup Iteration 2: 0.026 us/op
# Warmup Iteration 3: 0.026 us/op
# Warmup Iteration 4: 0.026 us/op
# Warmup Iteration 5: 0.026 us/op
# Warmup Iteration 6: 0.026 us/op
# Warmup Iteration 7: 0.026 us/op
# Warmup Iteration 8: 0.026 us/op
# Warmup Iteration 9: 0.026 us/op
# Warmup Iteration 10: 0.026 us/op
Iteration 1: 0.026 us/op
Iteration 2: 0.026 us/op
Iteration 3: 0.026 us/op
Iteration 4: 0.026 us/op
Iteration 5: 0.027 us/op
Iteration 6: 0.027 us/op
Iteration 7: 0.026 us/op
Iteration 8: 0.028 us/op
Iteration 9: 0.027 us/op
Iteration 10: 0.027 us/op
Iteration 11: 0.026 us/op
Iteration 12: 0.026 us/op
Iteration 13: 0.026 us/op
Iteration 14: 0.029 us/op
Iteration 15: 0.026 us/op
Iteration 16: 0.027 us/op
Iteration 17: 0.026 us/op
Iteration 18: 0.026 us/op
Iteration 19: 0.027 us/op
Iteration 20: 0.026 us/op
Result "stringBufferConcatenate":
0.026 ±(99.9%) 0.001 us/op [Average]
(min, avg, max) = (0.025, 0.026, 0.029), stdev = 0.001
CI (99.9%): [0.026, 0.026] (assumes normal distribution)
# JMH 1.12 (released 18 days ago)
# VM version: JDK 1.8.0_77, VM 25.77-b03
# VM invoker: C:\Program Files\Java\jre1.8.0_77\bin\java.exe
# VM options: -server -disablesystemassertions
# Warmup: 10 iterations, 3 s each
# Measurement: 20 iterations, 1 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Average time, time/op
# Benchmark: com.programtalk.java8.tutorial.ConcatenationComparision.stringBuilderConcatenate

# Run progress: 66.67% complete, ETA 00:02:31
# Fork: 1 of 3
# Warmup Iteration 1: 0.029 us/op
# Warmup Iteration 2: 0.026 us/op
# Warmup Iteration 3: 0.025 us/op
# Warmup Iteration 4: 0.025 us/op
# Warmup Iteration 5: 0.025 us/op
# Warmup Iteration 6: 0.025 us/op
# Warmup Iteration 7: 0.025 us/op
# Warmup Iteration 8: 0.025 us/op
# Warmup Iteration 9: 0.026 us/op
# Warmup Iteration 10: 0.027 us/op
Iteration 1: 0.025 us/op
Iteration 2: 0.025 us/op
Iteration 3: 0.028 us/op
Iteration 4: 0.028 us/op
Iteration 5: 0.026 us/op
Iteration 6: 0.026 us/op
Iteration 7: 0.025 us/op
Iteration 8: 0.025 us/op
Iteration 9: 0.025 us/op
Iteration 10: 0.027 us/op
Iteration 11: 0.026 us/op
Iteration 12: 0.026 us/op
Iteration 13: 0.025 us/op
Iteration 14: 0.025 us/op
Iteration 15: 0.025 us/op
Iteration 16: 0.028 us/op
Iteration 17: 0.028 us/op
Iteration 18: 0.027 us/op
Iteration 19: 0.025 us/op
Iteration 20: 0.025 us/op

# Run progress: 77.78% complete, ETA 00:01:40
# Fork: 2 of 3
# Warmup Iteration 1: 0.031 us/op
# Warmup Iteration 2: 0.026 us/op
# Warmup Iteration 3: 0.025 us/op
# Warmup Iteration 4: 0.025 us/op
# Warmup Iteration 5: 0.025 us/op
# Warmup Iteration 6: 0.026 us/op
# Warmup Iteration 7: 0.028 us/op
# Warmup Iteration 8: 0.026 us/op
# Warmup Iteration 9: 0.025 us/op
# Warmup Iteration 10: 0.027 us/op
Iteration 1: 0.026 us/op
Iteration 2: 0.027 us/op
Iteration 3: 0.025 us/op
Iteration 4: 0.026 us/op
Iteration 5: 0.025 us/op
Iteration 6: 0.027 us/op
Iteration 7: 0.026 us/op
Iteration 8: 0.026 us/op
Iteration 9: 0.028 us/op
Iteration 10: 0.030 us/op
Iteration 11: 0.026 us/op
Iteration 12: 0.025 us/op
Iteration 13: 0.025 us/op
Iteration 14: 0.025 us/op
Iteration 15: 0.025 us/op
Iteration 16: 0.025 us/op
Iteration 17: 0.025 us/op
Iteration 18: 0.025 us/op
Iteration 19: 0.025 us/op
Iteration 20: 0.026 us/op

# Run progress: 88.89% complete, ETA 00:00:50
# Fork: 3 of 3
# Warmup Iteration 1: 0.031 us/op
# Warmup Iteration 2: 0.025 us/op
# Warmup Iteration 3: 0.025 us/op
# Warmup Iteration 4: 0.026 us/op
# Warmup Iteration 5: 0.026 us/op
# Warmup Iteration 6: 0.025 us/op
# Warmup Iteration 7: 0.025 us/op
# Warmup Iteration 8: 0.026 us/op
# Warmup Iteration 9: 0.025 us/op
# Warmup Iteration 10: 0.025 us/op
Iteration 1: 0.025 us/op
Iteration 2: 0.025 us/op
Iteration 3: 0.025 us/op
Iteration 4: 0.025 us/op
Iteration 5: 0.025 us/op
Iteration 6: 0.025 us/op
Iteration 7: 0.025 us/op
Iteration 8: 0.026 us/op
Iteration 9: 0.025 us/op
Iteration 10: 0.025 us/op
Iteration 11: 0.025 us/op
Iteration 12: 0.025 us/op
Iteration 13: 0.025 us/op
Iteration 14: 0.025 us/op
Iteration 15: 0.027 us/op
Iteration 16: 0.025 us/op
Iteration 17: 0.025 us/op
Iteration 18: 0.025 us/op
Iteration 19: 0.025 us/op
Iteration 20: 0.025 us/op
Result "stringBuilderConcatenate":
0.026 ±(99.9%) 0.001 us/op [Average]
(min, avg, max) = (0.025, 0.026, 0.030), stdev = 0.001
CI (99.9%): [0.025, 0.026] (assumes normal distribution)
# Run complete. Total time: 00:07:34

Benchmark Mode Cnt Score Error Units
ConcatenationComparision.concatenatePlusEquals avgt 60 0.012 ± 0.001 us/op
ConcatenationComparision.stringBufferConcatenate avgt 60 0.026 ± 0.001 us/op
ConcatenationComparision.stringBuilderConcatenate avgt 60 0.026 ± 0.001 us/op

Conclusion

So from the above tests we can conclude the following points.

  1. If there are few strings to concatenate “+=”  or  “+” is better alternative as this means lesser code and hence leads to less maintenance.
  2. If there are lots of strings to concatenate then StringBuffer or StringBuilder is the better option
    • StringBuilder is recommended for single threaded use
    • StringBuffer is safe in concurrent environment
Like this post? Don’t forget to share it!