Why ‘+’ Can Outperform StringBuilder in Java: Real Benchmarks Explained
This article investigates the performance differences between Java’s ‘+’ operator, StringBuilder, and StringJoiner for string concatenation, presenting JUnit benchmark results for single and looped concatenations, analyzing compiled bytecode, and concluding when each method is optimal for readability and speed.
When concatenating strings in Java, developers often see IDE warnings suggesting the use of StringBuffer, StringBuilder, or StringJoiner, but the IDE may also recommend using the '+' operator.
Report any usage of StringBuffer, StringBuilder, or StringJoiner that could be replaced by a single java.lang.String concatenation. Using string concatenation makes the code shorter and simpler. The check reports only when the resulting concatenation is at least as efficient as the original code.
Normal Concatenation
Simple concatenation using '+' is commonly believed to be less efficient than StringBuilder, but since JDK 5 the compiler automatically transforms '+' operations into StringBuilder calls.
<code>/**
* Use + to concatenate strings
*/
public String concatenationStringByPlus(String prefix, int i) {
return prefix + "-" + i;
}
/**
* Use StringBuilder to concatenate strings
*/
public String concatenationStringByStringBuilder(String prefix, int i) {
return new StringBuilder().append(prefix).append("-").append(i).toString();
}
/**
* Test + concatenation performance
*/
@Test
public void testStringConcatenation01ByPlus() {
long startTime = System.currentTimeMillis();
int count = 100000;
for (int i = 0; i < count; i++) {
String str = concatenationStringByPlus("testStringConcatenation01ByStringBuilder:", i);
}
long endTime = System.currentTimeMillis();
System.out.println("testStringConcatenation01ByPlus, concatenated " + count + " times, took " + (endTime - startTime) + " ms");
}
/**
* Test StringBuilder concatenation performance
*/
@Test
public void testStringConcatenation02ByStringBuilder() {
long startTime = System.currentTimeMillis();
int count = 100000;
for (int i = 0; i < count; i++) {
String str = concatenationStringByStringBuilder("testStringConcatenation02ByStringBuilder:", i);
}
long endTime = System.currentTimeMillis();
System.out.println("testStringConcatenation02ByStringBuilder, concatenated " + count + " times, took " + (endTime - startTime) + " ms");
}
</code>Running the JUnit tests yields:
<code>testStringConcatenation01ByPlus, concatenated 100000 times, took 33 ms
testStringConcatenation02ByStringBuilder, concatenated 100000 times, took 36 ms
</code>The difference is minimal; considering the large number of iterations, the per‑operation cost is negligible, and various runtime factors can affect timing, so the two approaches are effectively equivalent for single concatenations.
Decompiling the compiled class file with
javap -c StringTest.classshows that both methods generate identical bytecode, confirming equal performance.
Since the performance is the same, using '+' for simple concatenation is recommended for its brevity and readability.
Loop Concatenation
When concatenating inside a loop, using '+' creates a new
StringBuilderon each iteration, dramatically increasing overhead. Directly reusing a single
StringBuilderinstance is far more efficient.
<code>/**
* Loop concatenation using +
*/
@Test
public void testLoopStringConcatenation03ByPlus() {
long startTime = System.currentTimeMillis();
int count = 10000;
String str = "testLoopStringConcatenation03ByPlus:";
for (int i = 0; i < count; i++) {
str = str + "-" + i;
}
System.out.println(str);
long endTime = System.currentTimeMillis();
System.out.println("testLoopStringConcatenation03ByPlus, concatenated " + count + " times, took " + (endTime - startTime) + " ms");
}
/**
* Loop concatenation using StringBuilder
*/
@Test
public void testLoopStringConcatenation04ByStringBuilder() {
long startTime = System.currentTimeMillis();
int count = 10000;
StringBuilder stringBuilder = new StringBuilder("testLoopStringConcatenation04ByStringBuilder:");
for (int i = 0; i < count; i++) {
stringBuilder.append("-");
stringBuilder.append(i);
}
String str = stringBuilder.toString();
System.out.println(str);
long endTime = System.currentTimeMillis();
System.out.println("testLoopStringConcatenation04ByStringBuilder, concatenated " + count + " times, took " + (endTime - startTime) + " ms");
}
</code>Test results:
<code>testLoopStringConcatenation03ByPlus, concatenated 10000 times, took 463 ms
testLoopStringConcatenation04ByStringBuilder, concatenated 10000 times, took 13 ms
</code>The loop using '+' is orders of magnitude slower than the StringBuilder version.
Conclusion
For simple, non‑looped string concatenation, using '+' is faster and more concise.
For concatenation inside loops, '+' incurs significant overhead; prefer StringBuilder for better performance.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.