DEV Community

Cover image for Effective Java: Beware the Performance of String Concatenation
Kyle Carter
Kyle Carter

Posted on • Edited on • Originally published at blog.scaledcode.com

Effective Java: Beware the Performance of String Concatenation

An attribute of the String type is that they are immutable. This allows for a number of good attributes. Another attribute of the String type is that Java provides some syntactic sugar to concatenate Strings by using the + operator. This is a very beneficial ability but putting these two capabilities together, immutability and simple contenation can lead us to accidentally cause performance issues. Let's consider an example:

public String concatenateStrings(int numberOfIterations) {
  String result = "";
  for (int i=0; i < numberOfIterations; i++) {
    result += randomStringOfLength(m);
  }
  return result;
}
Enter fullscreen mode Exit fullscreen mode

With a low value for numberOfIterations this can turn out to be fine. As the number of iterations goes up the cost goes up drastically. This is because the Strings can't be modified and must be copied. This not only costs a lot of compute power but also creates a lot of garbage for the garbage collector to clean up. Compare this to the much more performant version:

public String concatenateStrings(int numberOfIterations) {
  StringBuilder result = new StringBuilder();
  for (int i=0; i < numberOfIterations; i++) {
    result.append(randomStringOfLength(m));
  }
  return result.toString();
}
Enter fullscreen mode Exit fullscreen mode

This code uses a mutable holder to collect the Strings so it can concatenate them all at once.

So when should we use string concatenation and when should we use the StringBuilder. A good rule of thumb is to use a StringBuilder when concatenating in a loop. When concatenating a static number of Strings the performance won't get any better or worse from your initial testing so you won't be surprised by performance problems.

Top comments (2)

Collapse
 
elmuerte profile image
Michiel Hendriks

You might also want to initialize the size of the StringBuilder when you have a rough idea of the resulting size. In the above example

StringBuilder result = new StringBuilder(numberOfIterations * m);
Enter fullscreen mode Exit fullscreen mode

(Assuming numberOfIterations or m is not negative)

Collapse
 
kylec32 profile image
Kyle Carter

Yeah, you are exactly right. This is a great further optimization.