I was creating a demo to demonstrate how much faster StringBuilder
is than String concatenation.
I also wanted to demonstrate that String concatenation is the equivalent to making a new StringBuilder
for each append. I wanted to demonstrate this with the following 2 blocks:
Simply concatenate a String
String result = "";
for (int i = 0; i < 200000; i++) {
result += String.valueOf(i);
}
Create a new StringBuilder
for each concatenation
String result = "";
for (int i = 0; i < 200000; i++) {
result = new StringBuilder(result).append(String.valueOf(i)).toString();
}
My understanding was that the String concatenation example compiled to the same thing as creating a new StringBuilder
for each concatenation. I even decompiled the code to see the same result for both (I know decompiled code is not necessarily an exact representation of the written or compiled code).
Obviously using a single StringBuilder
for all appending ran in a fraction of the time of these 2 examples. But the weird thing is that the 2nd example (creating a new StringBuilder
manually each time) ran at nearly half the time of simple concatenation example. Why is creating a new StringBuilder
each time so much faster than concatenation?
(Using Java Adoptium Temurin 17 in case it matters)
Update For those asking for full code-
import java.util.Date;
public class App {
public static void main(String[] args) {
String result = "";
Date start = new Date();
for (int i = 0; i < 200000; i++) {
result = new StringBuilder(result).append(String.valueOf(i)).toString();
//result += String.valueOf(i);
}
Date end = new Date();
System.out.println(end.getTime() - start.getTime());
}
}
Like I said, it's a simple example. You can obviously just comment out the StringBuilder
line and uncomment the concat line to test the other example.
As I mentioned below, I know Date
is not meant to be used for metrics like this but it's a relatively simple example, and even without it, the difference is significantly noticeable in person.
I've tried this on 3 different Java Runtimes (Oracle 8, AdoptOpenJDK 11, and Adoptium Temurin 17), and while each one takes different amounts of time, the difference between the 2 is still pretty similar.