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.

</p>
<p>package com.programtalk.java8.tutorial;</p>
<p>import java.util.concurrent.TimeUnit;</p>
<p>import org.openjdk.jmh.annotations.Benchmark;<br />
import org.openjdk.jmh.annotations.BenchmarkMode;<br />
import org.openjdk.jmh.annotations.Fork;<br />
import org.openjdk.jmh.annotations.Mode;<br />
import org.openjdk.jmh.annotations.OutputTimeUnit;<br />
import org.openjdk.jmh.annotations.Scope;<br />
import org.openjdk.jmh.annotations.State;<br />
import org.openjdk.jmh.annotations.Warmup;</p>
<p>@State(Scope.Thread)<br />
@BenchmarkMode(Mode.AverageTime)<br />
@OutputTimeUnit(TimeUnit.MILLISECONDS)<br />
@Fork(value = 3, jvmArgsAppend = { &quot;-server&quot;, &quot;-disablesystemassertions&quot; })<br />
public class ConcatenationComparision {</p>
<p>	@Benchmark<br />
	@Warmup(iterations = 10, time = 3, timeUnit = TimeUnit.SECONDS)<br />
	public String stringBuilderConcatenate() {<br />
		StringBuilder sb = new StringBuilder();<br />
		for (int i = 0; &lt; 100000; i++) {<br />
			sb.append(&quot;string&quot;);<br />
		}<br />
		return sb.toString();<br />
	}</p>
<p>	@Benchmark<br />
	@Warmup(iterations = 10, time = 3, timeUnit = TimeUnit.SECONDS)<br />
	public String stringBufferConcatenate() {<br />
		StringBuffer sb = new StringBuffer();<br />
		for (int i = 0; i &lt; 100000; i++) {<br />
			sb.append(&quot;string&quot;);<br />
		}<br />
		return sb.toString();<br />
	}</p>
<p>	@Benchmark<br />
	@Warmup(iterations = 10, time = 3, timeUnit = TimeUnit.SECONDS)<br />
	public String concatenatePlusEquals() {<br />
		String st = &quot;hello&quot;;<br />
		for (int i = 0; i &lt; 100000; i++) {<br />
			st += &quot;string&quot;;<br />
		}<br />
		return st;<br />
	}<br />
}</p>
<p>

Overview of the results

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

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

<br />
# JMH 1.12 (released 18 days ago)<br />
# VM version: JDK 1.8.0_77, VM 25.77-b03<br />
# VM invoker: C:\Program Files\Java\jre1.8.0_77\bin\java.exe<br />
# VM options: -server -disablesystemassertions<br />
# Warmup: 10 iterations, 3 s each<br />
# Measurement: 20 iterations, 1 s each<br />
# Timeout: 10 min per iteration<br />
# Threads: 1 thread, will synchronize iterations<br />
# Benchmark mode: Average time, time/op<br />
# Benchmark: com.programtalk.java8.tutorial.ConcatenationComparision.concatenatePlusEquals</p>
<p># Run progress: 0.00% complete, ETA 00:07:30<br />
# Fork: 1 of 3<br />
# Warmup Iteration 1: 29026.249 ms/op<br />
# Warmup Iteration 2: 11515.075 ms/op<br />
# Warmup Iteration 3: 11625.230 ms/op<br />
# Warmup Iteration 4: 11265.016 ms/op<br />
# Warmup Iteration 5: 12201.576 ms/op<br />
# Warmup Iteration 6: 11502.628 ms/op<br />
# Warmup Iteration 7: 11404.251 ms/op<br />
# Warmup Iteration 8: 11782.064 ms/op<br />
# Warmup Iteration 9: 11176.152 ms/op<br />
# Warmup Iteration 10: 11012.261 ms/op<br />
Iteration 1: 11663.784 ms/op<br />
Iteration 2: 12123.228 ms/op<br />
Iteration 3: 11936.755 ms/op<br />
Iteration 4: 11827.529 ms/op<br />
Iteration 5: 11244.712 ms/op<br />
Iteration 6: 11809.777 ms/op<br />
Iteration 7: 12027.728 ms/op<br />
Iteration 8: 12152.749 ms/op<br />
Iteration 9: 11260.366 ms/op<br />
Iteration 10: 11470.332 ms/op<br />
Iteration 11: 11632.911 ms/op<br />
Iteration 12: 11460.662 ms/op<br />
Iteration 13: 11746.295 ms/op<br />
Iteration 14: 11453.243 ms/op<br />
Iteration 15: 11355.766 ms/op<br />
Iteration 16: 11051.642 ms/op<br />
Iteration 17: 11502.569 ms/op<br />
Iteration 18: 11686.925 ms/op<br />
Iteration 19: 11513.996 ms/op<br />
Iteration 20: 11755.533 ms/op</p>
<p># Run progress: 11.11% complete, ETA 00:48:45<br />
# Fork: 2 of 3<br />
# Warmup Iteration 1: 31015.111 ms/op<br />
# Warmup Iteration 2: 11847.680 ms/op<br />
# Warmup Iteration 3: 11187.849 ms/op<br />
# Warmup Iteration 4: 11712.085 ms/op<br />
# Warmup Iteration 5: 11746.606 ms/op<br />
# Warmup Iteration 6: 11683.458 ms/op<br />
# Warmup Iteration 7: 12043.231 ms/op<br />
# Warmup Iteration 8: 12126.888 ms/op<br />
# Warmup Iteration 9: 11803.950 ms/op<br />
# Warmup Iteration 10: 11565.470 ms/op<br />
Iteration 1: 11902.147 ms/op<br />
Iteration 2: 11516.863 ms/op<br />
Iteration 3: 11518.939 ms/op<br />
Iteration 4: 11511.284 ms/op<br />
Iteration 5: 11295.020 ms/op<br />
Iteration 6: 11677.118 ms/op<br />
Iteration 7: 11619.642 ms/op<br />
Iteration 8: 11964.386 ms/op<br />
Iteration 9: 11642.745 ms/op<br />
Iteration 10: 11717.145 ms/op<br />
Iteration 11: 11452.303 ms/op<br />
Iteration 12: 11482.042 ms/op<br />
Iteration 13: 11581.110 ms/op<br />
Iteration 14: 11654.061 ms/op<br />
Iteration 15: 11264.541 ms/op<br />
Iteration 16: 11243.485 ms/op<br />
Iteration 17: 11383.994 ms/op<br />
Iteration 18: 11506.032 ms/op<br />
Iteration 19: 11446.045 ms/op<br />
Iteration 20: 11403.822 ms/op</p>
<p># Run progress: 22.22% complete, ETA 00:42:47<br />
# Fork: 3 of 3<br />
# Warmup Iteration 1: 28695.977 ms/op<br />
# Warmup Iteration 2: 11444.238 ms/op<br />
# Warmup Iteration 3: 11664.799 ms/op<br />
# Warmup Iteration 4: 11655.362 ms/op<br />
# Warmup Iteration 5: 11561.321 ms/op<br />
# Warmup Iteration 6: 11466.525 ms/op<br />
# Warmup Iteration 7: 11413.860 ms/op<br />
# Warmup Iteration 8: 11446.732 ms/op<br />
# Warmup Iteration 9: 11537.595 ms/op<br />
# Warmup Iteration 10: 11347.037 ms/op<br />
Iteration 1: 11384.033 ms/op<br />
Iteration 2: 11460.320 ms/op<br />
Iteration 3: 11628.296 ms/op<br />
Iteration 4: 11905.415 ms/op<br />
Iteration 5: 11807.408 ms/op<br />
Iteration 6: 11305.356 ms/op<br />
Iteration 7: 11592.860 ms/op<br />
Iteration 8: 11490.144 ms/op<br />
Iteration 9: 11464.824 ms/op<br />
Iteration 10: 11637.315 ms/op<br />
Iteration 11: 11398.794 ms/op<br />
Iteration 12: 11649.445 ms/op<br />
Iteration 13: 12041.672 ms/op<br />
Iteration 14: 11541.617 ms/op<br />
Iteration 15: 11493.807 ms/op<br />
Iteration 16: 11270.454 ms/op<br />
Iteration 17: 11338.346 ms/op<br />
Iteration 18: 11419.955 ms/op<br />
Iteration 19: 11664.406 ms/op<br />
Iteration 20: 11385.820 ms/op</p>
<p>Result &quot;concatenatePlusEquals&quot;:<br />
 11572.325 ±(99.9%) 104.951 ms/op [Average]<br />
 (min, avg, max) = (11051.642, 11572.325, 12152.749), stdev = 234.739<br />
 CI (99.9%): [11467.374, 11677.277] (assumes normal distribution)</p>
<p># JMH 1.12 (released 18 days ago)<br />
# VM version: JDK 1.8.0_77, VM 25.77-b03<br />
# VM invoker: C:\Program Files\Java\jre1.8.0_77\bin\java.exe<br />
# VM options: -server -disablesystemassertions<br />
# Warmup: 10 iterations, 3 s each<br />
# Measurement: 20 iterations, 1 s each<br />
# Timeout: 10 min per iteration<br />
# Threads: 1 thread, will synchronize iterations<br />
# Benchmark mode: Average time, time/op<br />
# Benchmark: com.programtalk.java8.tutorial.ConcatenationComparision.stringBufferConcatenate</p>
<p># Run progress: 33.33% complete, ETA 00:36:34<br />
# Fork: 1 of 3<br />
# Warmup Iteration 1: 1.636 ms/op<br />
# Warmup Iteration 2: 1.406 ms/op<br />
# Warmup Iteration 3: 1.431 ms/op<br />
# Warmup Iteration 4: 1.455 ms/op<br />
# Warmup Iteration 5: 1.468 ms/op<br />
# Warmup Iteration 6: 1.437 ms/op<br />
# Warmup Iteration 7: 1.516 ms/op<br />
# Warmup Iteration 8: 1.409 ms/op<br />
# Warmup Iteration 9: 1.420 ms/op<br />
# Warmup Iteration 10: 1.438 ms/op<br />
Iteration 1: 1.520 ms/op<br />
Iteration 2: 1.435 ms/op<br />
Iteration 3: 1.402 ms/op<br />
Iteration 4: 1.511 ms/op<br />
Iteration 5: 1.405 ms/op<br />
Iteration 6: 1.413 ms/op<br />
Iteration 7: 1.451 ms/op<br />
Iteration 8: 1.437 ms/op<br />
Iteration 9: 1.432 ms/op<br />
Iteration 10: 1.443 ms/op<br />
Iteration 11: 1.415 ms/op<br />
Iteration 12: 1.408 ms/op<br />
Iteration 13: 1.431 ms/op<br />
Iteration 14: 1.431 ms/op<br />
Iteration 15: 1.427 ms/op<br />
Iteration 16: 1.467 ms/op<br />
Iteration 17: 1.407 ms/op<br />
Iteration 18: 1.401 ms/op<br />
Iteration 19: 1.406 ms/op<br />
Iteration 20: 1.402 ms/op</p>
<p># Run progress: 44.44% complete, ETA 00:23:54<br />
# Fork: 2 of 3<br />
# Warmup Iteration 1: 1.625 ms/op<br />
# Warmup Iteration 2: 1.413 ms/op<br />
# Warmup Iteration 3: 1.464 ms/op<br />
# Warmup Iteration 4: 1.414 ms/op<br />
# Warmup Iteration 5: 1.430 ms/op<br />
# Warmup Iteration 6: 1.423 ms/op<br />
# Warmup Iteration 7: 1.427 ms/op<br />
# Warmup Iteration 8: 1.443 ms/op<br />
# Warmup Iteration 9: 1.415 ms/op<br />
# Warmup Iteration 10: 1.426 ms/op<br />
Iteration 1: 1.444 ms/op<br />
Iteration 2: 1.466 ms/op<br />
Iteration 3: 1.447 ms/op<br />
Iteration 4: 1.412 ms/op<br />
Iteration 5: 1.442 ms/op<br />
Iteration 6: 1.457 ms/op<br />
Iteration 7: 1.462 ms/op<br />
Iteration 8: 1.413 ms/op<br />
Iteration 9: 1.438 ms/op<br />
Iteration 10: 1.427 ms/op<br />
Iteration 11: 1.430 ms/op<br />
Iteration 12: 1.499 ms/op<br />
Iteration 13: 1.606 ms/op<br />
Iteration 14: 1.453 ms/op<br />
Iteration 15: 1.433 ms/op<br />
Iteration 16: 1.410 ms/op<br />
Iteration 17: 1.436 ms/op<br />
Iteration 18: 1.426 ms/op<br />
Iteration 19: 1.520 ms/op<br />
Iteration 20: 1.496 ms/op</p>
<p># Run progress: 55.56% complete, ETA 00:15:58<br />
# Fork: 3 of 3<br />
# Warmup Iteration 1: 1.720 ms/op<br />
# Warmup Iteration 2: 1.507 ms/op<br />
# Warmup Iteration 3: 1.457 ms/op<br />
# Warmup Iteration 4: 1.457 ms/op<br />
# Warmup Iteration 5: 1.443 ms/op<br />
# Warmup Iteration 6: 1.507 ms/op<br />
# Warmup Iteration 7: 1.584 ms/op<br />
# Warmup Iteration 8: 1.901 ms/op<br />
# Warmup Iteration 9: 1.701 ms/op<br />
# Warmup Iteration 10: 2.060 ms/op<br />
Iteration 1: 1.866 ms/op<br />
Iteration 2: 1.684 ms/op<br />
Iteration 3: 1.490 ms/op<br />
Iteration 4: 1.636 ms/op<br />
Iteration 5: 1.507 ms/op<br />
Iteration 6: 1.450 ms/op<br />
Iteration 7: 1.466 ms/op<br />
Iteration 8: 1.443 ms/op<br />
Iteration 9: 1.481 ms/op<br />
Iteration 10: 1.448 ms/op<br />
Iteration 11: 1.500 ms/op<br />
Iteration 12: 1.609 ms/op<br />
Iteration 13: 1.545 ms/op<br />
Iteration 14: 1.469 ms/op<br />
Iteration 15: 1.522 ms/op<br />
Iteration 16: 1.488 ms/op<br />
Iteration 17: 1.443 ms/op<br />
Iteration 18: 1.471 ms/op<br />
Iteration 19: 1.492 ms/op<br />
Iteration 20: 1.502 ms/op</p>
<p>Result &quot;stringBufferConcatenate&quot;:<br />
 1.471 ±(99.9%) 0.035 ms/op [Average]<br />
 (min, avg, max) = (1.401, 1.471, 1.866), stdev = 0.078<br />
 CI (99.9%): [1.436, 1.506] (assumes normal distribution)</p>
<p># JMH 1.12 (released 18 days ago)<br />
# VM version: JDK 1.8.0_77, VM 25.77-b03<br />
# VM invoker: C:\Program Files\Java\jre1.8.0_77\bin\java.exe<br />
# VM options: -server -disablesystemassertions<br />
# Warmup: 10 iterations, 3 s each<br />
# Measurement: 20 iterations, 1 s each<br />
# Timeout: 10 min per iteration<br />
# Threads: 1 thread, will synchronize iterations<br />
# Benchmark mode: Average time, time/op<br />
# Benchmark: com.programtalk.java8.tutorial.ConcatenationComparision.stringBuilderConcatenate</p>
<p># Run progress: 66.67% complete, ETA 00:10:24<br />
# Fork: 1 of 3<br />
# Warmup Iteration 1: 1.663 ms/op<br />
# Warmup Iteration 2: 1.484 ms/op<br />
# Warmup Iteration 3: 1.528 ms/op<br />
# Warmup Iteration 4: 1.482 ms/op<br />
# Warmup Iteration 5: 1.476 ms/op<br />
# Warmup Iteration 6: 1.533 ms/op<br />
# Warmup Iteration 7: 1.533 ms/op<br />
# Warmup Iteration 8: 1.591 ms/op<br />
# Warmup Iteration 9: 1.748 ms/op<br />
# Warmup Iteration 10: 1.481 ms/op<br />
Iteration 1: 1.479 ms/op<br />
Iteration 2: 1.467 ms/op<br />
Iteration 3: 1.500 ms/op<br />
Iteration 4: 1.552 ms/op<br />
Iteration 5: 1.502 ms/op<br />
Iteration 6: 1.509 ms/op<br />
Iteration 7: 1.502 ms/op<br />
Iteration 8: 1.604 ms/op<br />
Iteration 9: 1.685 ms/op<br />
Iteration 10: 1.639 ms/op<br />
Iteration 11: 1.523 ms/op<br />
Iteration 12: 1.503 ms/op<br />
Iteration 13: 1.580 ms/op<br />
Iteration 14: 1.560 ms/op<br />
Iteration 15: 1.681 ms/op<br />
Iteration 16: 1.479 ms/op<br />
Iteration 17: 1.524 ms/op<br />
Iteration 18: 1.486 ms/op<br />
Iteration 19: 1.503 ms/op<br />
Iteration 20: 1.487 ms/op</p>
<p># Run progress: 77.78% complete, ETA 00:06:11<br />
# Fork: 2 of 3<br />
# Warmup Iteration 1: 1.665 ms/op<br />
# Warmup Iteration 2: 1.545 ms/op<br />
# Warmup Iteration 3: 1.525 ms/op<br />
# Warmup Iteration 4: 1.566 ms/op<br />
# Warmup Iteration 5: 1.545 ms/op<br />
# Warmup Iteration 6: 1.538 ms/op<br />
# Warmup Iteration 7: 1.514 ms/op<br />
# Warmup Iteration 8: 1.550 ms/op<br />
# Warmup Iteration 9: 1.538 ms/op<br />
# Warmup Iteration 10: 1.533 ms/op<br />
Iteration 1: 1.517 ms/op<br />
Iteration 2: 1.543 ms/op<br />
Iteration 3: 1.510 ms/op<br />
Iteration 4: 1.549 ms/op<br />
Iteration 5: 1.540 ms/op<br />
Iteration 6: 1.522 ms/op<br />
Iteration 7: 1.513 ms/op<br />
Iteration 8: 1.601 ms/op<br />
Iteration 9: 1.521 ms/op<br />
Iteration 10: 1.501 ms/op<br />
Iteration 11: 1.522 ms/op<br />
Iteration 12: 1.516 ms/op<br />
Iteration 13: 1.524 ms/op<br />
Iteration 14: 1.543 ms/op<br />
Iteration 15: 1.569 ms/op<br />
Iteration 16: 1.565 ms/op<br />
Iteration 17: 1.516 ms/op<br />
Iteration 18: 1.545 ms/op<br />
Iteration 19: 1.563 ms/op<br />
Iteration 20: 1.520 ms/op</p>
<p># Run progress: 88.89% complete, ETA 00:02:48<br />
# Fork: 3 of 3<br />
# Warmup Iteration 1: 1.647 ms/op<br />
# Warmup Iteration 2: 1.495 ms/op<br />
# Warmup Iteration 3: 1.494 ms/op<br />
# Warmup Iteration 4: 1.514 ms/op<br />
# Warmup Iteration 5: 1.497 ms/op<br />
# Warmup Iteration 6: 1.499 ms/op<br />
# Warmup Iteration 7: 1.537 ms/op<br />
# Warmup Iteration 8: 1.498 ms/op<br />
# Warmup Iteration 9: 1.492 ms/op<br />
# Warmup Iteration 10: 1.509 ms/op<br />
Iteration 1: 1.502 ms/op<br />
Iteration 2: 1.522 ms/op<br />
Iteration 3: 1.539 ms/op<br />
Iteration 4: 1.505 ms/op<br />
Iteration 5: 1.498 ms/op<br />
Iteration 6: 1.475 ms/op<br />
Iteration 7: 1.544 ms/op<br />
Iteration 8: 1.476 ms/op<br />
Iteration 9: 1.483 ms/op<br />
Iteration 10: 1.507 ms/op<br />
Iteration 11: 1.478 ms/op<br />
Iteration 12: 1.495 ms/op<br />
Iteration 13: 1.500 ms/op<br />
Iteration 14: 1.551 ms/op<br />
Iteration 15: 1.489 ms/op<br />
Iteration 16: 1.487 ms/op<br />
Iteration 17: 1.542 ms/op<br />
Iteration 18: 1.494 ms/op<br />
Iteration 19: 1.491 ms/op<br />
Iteration 20: 1.476 ms/op</p>
<p>Result &quot;stringBuilderConcatenate&quot;:<br />
 1.525 ±(99.9%) 0.020 ms/op [Average]<br />
 (min, avg, max) = (1.467, 1.525, 1.685), stdev = 0.046<br />
 CI (99.9%): [1.505, 1.546] (assumes normal distribution)</p>
<p># Run complete. Total time: 00:23:20</p>
<p>Benchmark Mode Cnt Score Error Units<br />
ConcatenationComparision.concatenatePlusEquals avgt 60 11572.325 ± 104.951 ms/op<br />
ConcatenationComparision.stringBufferConcatenate avgt 60 1.471 ± 0.035 ms/op<br />
ConcatenationComparision.stringBuilderConcatenate avgt 60 1.525 ± 0.020 ms/op</p>
<p>

 

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.

</p>
<p>package com.programtalk.java8.tutorial;</p>
<p>import java.util.concurrent.TimeUnit;</p>
<p>import org.openjdk.jmh.annotations.Benchmark;<br />
import org.openjdk.jmh.annotations.BenchmarkMode;<br />
import org.openjdk.jmh.annotations.Fork;<br />
import org.openjdk.jmh.annotations.Mode;<br />
import org.openjdk.jmh.annotations.OutputTimeUnit;<br />
import org.openjdk.jmh.annotations.Scope;<br />
import org.openjdk.jmh.annotations.State;<br />
import org.openjdk.jmh.annotations.Warmup;</p>
<p>@State(Scope.Thread)<br />
@BenchmarkMode(Mode.AverageTime)<br />
@OutputTimeUnit(TimeUnit.MICROSECONDS)<br />
@Fork(value = 3, jvmArgsAppend = { &quot;-server&quot;, &quot;-disablesystemassertions&quot; })<br />
public class ConcatenationComparision {</p>
<p>	@Benchmark<br />
	@Warmup(iterations = 10, time = 3, timeUnit = TimeUnit.SECONDS)<br />
	public String stringBuilderConcatenate() {<br />
		StringBuilder sb = new StringBuilder(&quot;hello&quot;);<br />
		sb.append(&quot;string&quot;);<br />
		return sb.toString();<br />
	}</p>
<p>	@Benchmark<br />
	@Warmup(iterations = 10, time = 3, timeUnit = TimeUnit.SECONDS)<br />
	public String stringBufferConcatenate() {<br />
		StringBuffer sb = new StringBuffer(&quot;hello&quot;);<br />
		sb.append(&quot;string&quot;);<br />
		return sb.toString();<br />
	}</p>
<p>	@Benchmark<br />
	@Warmup(iterations = 10, time = 3, timeUnit = TimeUnit.SECONDS)<br />
	public String concatenatePlusEquals() {<br />
		String st = &quot;hello&quot;;<br />
		return st += &quot;string&quot;;<br />
	}<br />
}</p>
<p>

Overview of the results

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

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

Full log

</p>
<p># JMH 1.12 (released 18 days ago)<br />
# VM version: JDK 1.8.0_77, VM 25.77-b03<br />
# VM invoker: C:\Program Files\Java\jre1.8.0_77\bin\java.exe<br />
# VM options: -server -disablesystemassertions<br />
# Warmup: 10 iterations, 3 s each<br />
# Measurement: 20 iterations, 1 s each<br />
# Timeout: 10 min per iteration<br />
# Threads: 1 thread, will synchronize iterations<br />
# Benchmark mode: Average time, time/op<br />
# Benchmark: com.programtalk.java8.tutorial.ConcatenationComparision.concatenatePlusEquals</p>
<p># Run progress: 0.00% complete, ETA 00:07:30<br />
# Fork: 1 of 3<br />
# Warmup Iteration 1: 0.014 us/op<br />
# Warmup Iteration 2: 0.012 us/op<br />
# Warmup Iteration 3: 0.012 us/op<br />
# Warmup Iteration 4: 0.012 us/op<br />
# Warmup Iteration 5: 0.012 us/op<br />
# Warmup Iteration 6: 0.012 us/op<br />
# Warmup Iteration 7: 0.012 us/op<br />
# Warmup Iteration 8: 0.012 us/op<br />
# Warmup Iteration 9: 0.012 us/op<br />
# Warmup Iteration 10: 0.012 us/op<br />
Iteration 1: 0.012 us/op<br />
Iteration 2: 0.012 us/op<br />
Iteration 3: 0.012 us/op<br />
Iteration 4: 0.012 us/op<br />
Iteration 5: 0.012 us/op<br />
Iteration 6: 0.012 us/op<br />
Iteration 7: 0.012 us/op<br />
Iteration 8: 0.012 us/op<br />
Iteration 9: 0.012 us/op<br />
Iteration 10: 0.012 us/op<br />
Iteration 11: 0.012 us/op<br />
Iteration 12: 0.012 us/op<br />
Iteration 13: 0.012 us/op<br />
Iteration 14: 0.012 us/op<br />
Iteration 15: 0.012 us/op<br />
Iteration 16: 0.012 us/op<br />
Iteration 17: 0.012 us/op<br />
Iteration 18: 0.012 us/op<br />
Iteration 19: 0.013 us/op<br />
Iteration 20: 0.012 us/op</p>
<p># Run progress: 11.11% complete, ETA 00:06:43<br />
# Fork: 2 of 3<br />
# Warmup Iteration 1: 0.014 us/op<br />
# Warmup Iteration 2: 0.012 us/op<br />
# Warmup Iteration 3: 0.012 us/op<br />
# Warmup Iteration 4: 0.012 us/op<br />
# Warmup Iteration 5: 0.012 us/op<br />
# Warmup Iteration 6: 0.012 us/op<br />
# Warmup Iteration 7: 0.012 us/op<br />
# Warmup Iteration 8: 0.012 us/op<br />
# Warmup Iteration 9: 0.012 us/op<br />
# Warmup Iteration 10: 0.012 us/op<br />
Iteration 1: 0.012 us/op<br />
Iteration 2: 0.012 us/op<br />
Iteration 3: 0.012 us/op<br />
Iteration 4: 0.012 us/op<br />
Iteration 5: 0.012 us/op<br />
Iteration 6: 0.012 us/op<br />
Iteration 7: 0.012 us/op<br />
Iteration 8: 0.012 us/op<br />
Iteration 9: 0.012 us/op<br />
Iteration 10: 0.012 us/op<br />
Iteration 11: 0.012 us/op<br />
Iteration 12: 0.012 us/op<br />
Iteration 13: 0.012 us/op<br />
Iteration 14: 0.012 us/op<br />
Iteration 15: 0.012 us/op<br />
Iteration 16: 0.012 us/op<br />
Iteration 17: 0.012 us/op<br />
Iteration 18: 0.012 us/op<br />
Iteration 19: 0.012 us/op<br />
Iteration 20: 0.012 us/op</p>
<p># Run progress: 22.22% complete, ETA 00:05:53<br />
# Fork: 3 of 3<br />
# Warmup Iteration 1: 0.014 us/op<br />
# Warmup Iteration 2: 0.012 us/op<br />
# Warmup Iteration 3: 0.012 us/op<br />
# Warmup Iteration 4: 0.012 us/op<br />
# Warmup Iteration 5: 0.012 us/op<br />
# Warmup Iteration 6: 0.012 us/op<br />
# Warmup Iteration 7: 0.012 us/op<br />
# Warmup Iteration 8: 0.012 us/op<br />
# Warmup Iteration 9: 0.012 us/op<br />
# Warmup Iteration 10: 0.012 us/op<br />
Iteration 1: 0.012 us/op<br />
Iteration 2: 0.012 us/op<br />
Iteration 3: 0.012 us/op<br />
Iteration 4: 0.012 us/op<br />
Iteration 5: 0.012 us/op<br />
Iteration 6: 0.012 us/op<br />
Iteration 7: 0.012 us/op<br />
Iteration 8: 0.012 us/op<br />
Iteration 9: 0.012 us/op<br />
Iteration 10: 0.012 us/op<br />
Iteration 11: 0.012 us/op<br />
Iteration 12: 0.012 us/op<br />
Iteration 13: 0.012 us/op<br />
Iteration 14: 0.012 us/op<br />
Iteration 15: 0.012 us/op<br />
Iteration 16: 0.012 us/op<br />
Iteration 17: 0.012 us/op<br />
Iteration 18: 0.012 us/op<br />
Iteration 19: 0.012 us/op<br />
Iteration 20: 0.012 us/op<br />
Result &quot;concatenatePlusEquals&quot;:<br />
0.012 ±(99.9%) 0.001 us/op [Average]<br />
(min, avg, max) = (0.012, 0.012, 0.013), stdev = 0.001<br />
CI (99.9%): [0.012, 0.012] (assumes normal distribution)<br />
# JMH 1.12 (released 18 days ago)<br />
# VM version: JDK 1.8.0_77, VM 25.77-b03<br />
# VM invoker: C:\Program Files\Java\jre1.8.0_77\bin\java.exe<br />
# VM options: -server -disablesystemassertions<br />
# Warmup: 10 iterations, 3 s each<br />
# Measurement: 20 iterations, 1 s each<br />
# Timeout: 10 min per iteration<br />
# Threads: 1 thread, will synchronize iterations<br />
# Benchmark mode: Average time, time/op<br />
# Benchmark: com.programtalk.java8.tutorial.ConcatenationComparision.stringBufferConcatenate</p>
<p># Run progress: 33.33% complete, ETA 00:05:02<br />
# Fork: 1 of 3<br />
# Warmup Iteration 1: 0.030 us/op<br />
# Warmup Iteration 2: 0.026 us/op<br />
# Warmup Iteration 3: 0.026 us/op<br />
# Warmup Iteration 4: 0.026 us/op<br />
# Warmup Iteration 5: 0.026 us/op<br />
# Warmup Iteration 6: 0.027 us/op<br />
# Warmup Iteration 7: 0.026 us/op<br />
# Warmup Iteration 8: 0.026 us/op<br />
# Warmup Iteration 9: 0.027 us/op<br />
# Warmup Iteration 10: 0.026 us/op<br />
Iteration 1: 0.026 us/op<br />
Iteration 2: 0.026 us/op<br />
Iteration 3: 0.025 us/op<br />
Iteration 4: 0.026 us/op<br />
Iteration 5: 0.026 us/op<br />
Iteration 6: 0.026 us/op<br />
Iteration 7: 0.026 us/op<br />
Iteration 8: 0.026 us/op<br />
Iteration 9: 0.026 us/op<br />
Iteration 10: 0.025 us/op<br />
Iteration 11: 0.026 us/op<br />
Iteration 12: 0.026 us/op<br />
Iteration 13: 0.026 us/op<br />
Iteration 14: 0.026 us/op<br />
Iteration 15: 0.026 us/op<br />
Iteration 16: 0.026 us/op<br />
Iteration 17: 0.026 us/op<br />
Iteration 18: 0.026 us/op<br />
Iteration 19: 0.026 us/op<br />
Iteration 20: 0.026 us/op</p>
<p># Run progress: 44.44% complete, ETA 00:04:12<br />
# Fork: 2 of 3<br />
# Warmup Iteration 1: 0.030 us/op<br />
# Warmup Iteration 2: 0.026 us/op<br />
# Warmup Iteration 3: 0.026 us/op<br />
# Warmup Iteration 4: 0.026 us/op<br />
# Warmup Iteration 5: 0.026 us/op<br />
# Warmup Iteration 6: 0.026 us/op<br />
# Warmup Iteration 7: 0.026 us/op<br />
# Warmup Iteration 8: 0.026 us/op<br />
# Warmup Iteration 9: 0.026 us/op<br />
# Warmup Iteration 10: 0.026 us/op<br />
Iteration 1: 0.026 us/op<br />
Iteration 2: 0.026 us/op<br />
Iteration 3: 0.026 us/op<br />
Iteration 4: 0.026 us/op<br />
Iteration 5: 0.026 us/op<br />
Iteration 6: 0.028 us/op<br />
Iteration 7: 0.026 us/op<br />
Iteration 8: 0.026 us/op<br />
Iteration 9: 0.026 us/op<br />
Iteration 10: 0.026 us/op<br />
Iteration 11: 0.026 us/op<br />
Iteration 12: 0.026 us/op<br />
Iteration 13: 0.026 us/op<br />
Iteration 14: 0.026 us/op<br />
Iteration 15: 0.026 us/op<br />
Iteration 16: 0.026 us/op<br />
Iteration 17: 0.026 us/op<br />
Iteration 18: 0.026 us/op<br />
Iteration 19: 0.026 us/op<br />
Iteration 20: 0.027 us/op</p>
<p># Run progress: 55.56% complete, ETA 00:03:21<br />
# Fork: 3 of 3<br />
# Warmup Iteration 1: 0.030 us/op<br />
# Warmup Iteration 2: 0.026 us/op<br />
# Warmup Iteration 3: 0.026 us/op<br />
# Warmup Iteration 4: 0.026 us/op<br />
# Warmup Iteration 5: 0.026 us/op<br />
# Warmup Iteration 6: 0.026 us/op<br />
# Warmup Iteration 7: 0.026 us/op<br />
# Warmup Iteration 8: 0.026 us/op<br />
# Warmup Iteration 9: 0.026 us/op<br />
# Warmup Iteration 10: 0.026 us/op<br />
Iteration 1: 0.026 us/op<br />
Iteration 2: 0.026 us/op<br />
Iteration 3: 0.026 us/op<br />
Iteration 4: 0.026 us/op<br />
Iteration 5: 0.027 us/op<br />
Iteration 6: 0.027 us/op<br />
Iteration 7: 0.026 us/op<br />
Iteration 8: 0.028 us/op<br />
Iteration 9: 0.027 us/op<br />
Iteration 10: 0.027 us/op<br />
Iteration 11: 0.026 us/op<br />
Iteration 12: 0.026 us/op<br />
Iteration 13: 0.026 us/op<br />
Iteration 14: 0.029 us/op<br />
Iteration 15: 0.026 us/op<br />
Iteration 16: 0.027 us/op<br />
Iteration 17: 0.026 us/op<br />
Iteration 18: 0.026 us/op<br />
Iteration 19: 0.027 us/op<br />
Iteration 20: 0.026 us/op<br />
Result &quot;stringBufferConcatenate&quot;:<br />
0.026 ±(99.9%) 0.001 us/op [Average]<br />
(min, avg, max) = (0.025, 0.026, 0.029), stdev = 0.001<br />
CI (99.9%): [0.026, 0.026] (assumes normal distribution)<br />
# JMH 1.12 (released 18 days ago)<br />
# VM version: JDK 1.8.0_77, VM 25.77-b03<br />
# VM invoker: C:\Program Files\Java\jre1.8.0_77\bin\java.exe<br />
# VM options: -server -disablesystemassertions<br />
# Warmup: 10 iterations, 3 s each<br />
# Measurement: 20 iterations, 1 s each<br />
# Timeout: 10 min per iteration<br />
# Threads: 1 thread, will synchronize iterations<br />
# Benchmark mode: Average time, time/op<br />
# Benchmark: com.programtalk.java8.tutorial.ConcatenationComparision.stringBuilderConcatenate</p>
<p># Run progress: 66.67% complete, ETA 00:02:31<br />
# Fork: 1 of 3<br />
# Warmup Iteration 1: 0.029 us/op<br />
# Warmup Iteration 2: 0.026 us/op<br />
# Warmup Iteration 3: 0.025 us/op<br />
# Warmup Iteration 4: 0.025 us/op<br />
# Warmup Iteration 5: 0.025 us/op<br />
# Warmup Iteration 6: 0.025 us/op<br />
# Warmup Iteration 7: 0.025 us/op<br />
# Warmup Iteration 8: 0.025 us/op<br />
# Warmup Iteration 9: 0.026 us/op<br />
# Warmup Iteration 10: 0.027 us/op<br />
Iteration 1: 0.025 us/op<br />
Iteration 2: 0.025 us/op<br />
Iteration 3: 0.028 us/op<br />
Iteration 4: 0.028 us/op<br />
Iteration 5: 0.026 us/op<br />
Iteration 6: 0.026 us/op<br />
Iteration 7: 0.025 us/op<br />
Iteration 8: 0.025 us/op<br />
Iteration 9: 0.025 us/op<br />
Iteration 10: 0.027 us/op<br />
Iteration 11: 0.026 us/op<br />
Iteration 12: 0.026 us/op<br />
Iteration 13: 0.025 us/op<br />
Iteration 14: 0.025 us/op<br />
Iteration 15: 0.025 us/op<br />
Iteration 16: 0.028 us/op<br />
Iteration 17: 0.028 us/op<br />
Iteration 18: 0.027 us/op<br />
Iteration 19: 0.025 us/op<br />
Iteration 20: 0.025 us/op</p>
<p># Run progress: 77.78% complete, ETA 00:01:40<br />
# Fork: 2 of 3<br />
# Warmup Iteration 1: 0.031 us/op<br />
# Warmup Iteration 2: 0.026 us/op<br />
# Warmup Iteration 3: 0.025 us/op<br />
# Warmup Iteration 4: 0.025 us/op<br />
# Warmup Iteration 5: 0.025 us/op<br />
# Warmup Iteration 6: 0.026 us/op<br />
# Warmup Iteration 7: 0.028 us/op<br />
# Warmup Iteration 8: 0.026 us/op<br />
# Warmup Iteration 9: 0.025 us/op<br />
# Warmup Iteration 10: 0.027 us/op<br />
Iteration 1: 0.026 us/op<br />
Iteration 2: 0.027 us/op<br />
Iteration 3: 0.025 us/op<br />
Iteration 4: 0.026 us/op<br />
Iteration 5: 0.025 us/op<br />
Iteration 6: 0.027 us/op<br />
Iteration 7: 0.026 us/op<br />
Iteration 8: 0.026 us/op<br />
Iteration 9: 0.028 us/op<br />
Iteration 10: 0.030 us/op<br />
Iteration 11: 0.026 us/op<br />
Iteration 12: 0.025 us/op<br />
Iteration 13: 0.025 us/op<br />
Iteration 14: 0.025 us/op<br />
Iteration 15: 0.025 us/op<br />
Iteration 16: 0.025 us/op<br />
Iteration 17: 0.025 us/op<br />
Iteration 18: 0.025 us/op<br />
Iteration 19: 0.025 us/op<br />
Iteration 20: 0.026 us/op</p>
<p># Run progress: 88.89% complete, ETA 00:00:50<br />
# Fork: 3 of 3<br />
# Warmup Iteration 1: 0.031 us/op<br />
# Warmup Iteration 2: 0.025 us/op<br />
# Warmup Iteration 3: 0.025 us/op<br />
# Warmup Iteration 4: 0.026 us/op<br />
# Warmup Iteration 5: 0.026 us/op<br />
# Warmup Iteration 6: 0.025 us/op<br />
# Warmup Iteration 7: 0.025 us/op<br />
# Warmup Iteration 8: 0.026 us/op<br />
# Warmup Iteration 9: 0.025 us/op<br />
# Warmup Iteration 10: 0.025 us/op<br />
Iteration 1: 0.025 us/op<br />
Iteration 2: 0.025 us/op<br />
Iteration 3: 0.025 us/op<br />
Iteration 4: 0.025 us/op<br />
Iteration 5: 0.025 us/op<br />
Iteration 6: 0.025 us/op<br />
Iteration 7: 0.025 us/op<br />
Iteration 8: 0.026 us/op<br />
Iteration 9: 0.025 us/op<br />
Iteration 10: 0.025 us/op<br />
Iteration 11: 0.025 us/op<br />
Iteration 12: 0.025 us/op<br />
Iteration 13: 0.025 us/op<br />
Iteration 14: 0.025 us/op<br />
Iteration 15: 0.027 us/op<br />
Iteration 16: 0.025 us/op<br />
Iteration 17: 0.025 us/op<br />
Iteration 18: 0.025 us/op<br />
Iteration 19: 0.025 us/op<br />
Iteration 20: 0.025 us/op<br />
Result &quot;stringBuilderConcatenate&quot;:<br />
0.026 ±(99.9%) 0.001 us/op [Average]<br />
(min, avg, max) = (0.025, 0.026, 0.030), stdev = 0.001<br />
CI (99.9%): [0.025, 0.026] (assumes normal distribution)<br />
# Run complete. Total time: 00:07:34</p>
<p>Benchmark Mode Cnt Score Error Units<br />
ConcatenationComparision.concatenatePlusEquals avgt 60 0.012 ± 0.001 us/op<br />
ConcatenationComparision.stringBufferConcatenate avgt 60 0.026 ± 0.001 us/op<br />
ConcatenationComparision.stringBuilderConcatenate avgt 60 0.026 ± 0.001 us/op</p>
<p>

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!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.