For performance reasons, the use of += (String concatenation) is discouraged. The reason why is: Java String is an immutable, every time a new concatenation is done a new String is created (the new one has a different fingerprint from the older one already in the String pool ). Creating new strings puts pressure on the GC and slows down the program: object creation is expensive.
Below code should make it more practical and clear at the same time.
public static void main(String[] args) { // warming up for(int i = 0; i < 100; i++) RandomStringUtils.randomAlphanumeric(1024); final StringBuilder appender = new StringBuilder(); for(int i = 0; i < 100; i++) appender.append(RandomStringUtils.randomAlphanumeric(i)); // testing for(int i = 1; i <= 10000; i*=10) test(i); } public static void test(final int howMany) { List<String> samples = new ArrayList<>(howMany); for(int i = 0; i < howMany; i++) samples.add(RandomStringUtils.randomAlphabetic(128)); final StringBuilder builder = new StringBuilder(); long start = System.nanoTime(); for(String sample: samples) builder.append(sample); builder.toString(); long elapsed = System.nanoTime() - start; System.out.printf("builder - %d - elapsed: %dus\n", howMany, elapsed / 1000); String accumulator = ""; start = System.nanoTime(); for(String sample: samples) accumulator += sample; elapsed = System.nanoTime() - start; System.out.printf("concatenation - %d - elapsed: %dus\n", howMany, elapsed / (int) 1e3); start = System.nanoTime(); String newOne = null; for(String sample: samples) newOne = new String(sample); elapsed = System.nanoTime() - start; System.out.printf("creation - %d - elapsed: %dus\n\n", howMany, elapsed / 1000); }
Results for a run are reported below.
builder - 1 - elapsed: 132us concatenation - 1 - elapsed: 4us creation - 1 - elapsed: 5us builder - 10 - elapsed: 9us concatenation - 10 - elapsed: 26us creation - 10 - elapsed: 5us builder - 100 - elapsed: 77us concatenation - 100 - elapsed: 1669us creation - 100 - elapsed: 43us builder - 1000 - elapsed: 511us concatenation - 1000 - elapsed: 111504us creation - 1000 - elapsed: 282us builder - 10000 - elapsed: 3364us concatenation - 10000 - elapsed: 5709793us creation - 10000 - elapsed: 972us
Not considering the results for 1 concatenation (JIT was not yet doing its job), even for 10 concatenations the performance penalty is relevant; for thousands of concatenations, the difference is huge.
Lessons learned from this very quick experiment (easily reproducible with the above code): never use the += to concatenate strings together, even in very basic cases where a few concatenations are needed (as said, creating new strings is expensive anyway and puts pressure on the GC).
StringBuilderhow much size to allocate upfront otherwise it will, if it runs out of space, have to double the size by creating a newchar[]array then copy data over - which is costly. You can cheat by giving the size and then there is no need for this array creation - so if you think your string will be ~100 chars long then you can set the StringBuilder to that size and it will never have to expand internally.