Is chain of StringBuilder.append more efficient than string concatenation?

Java

Java Problem Overview


According to Netbeans hint named Use chain of .append methods instead of string concatenation

>Looks for string concatenation in the parameter of an invocation of the append method of StringBuilder or StringBuffer.

Is StringBuilder.append() really more efficient than strings concatenation?

Code sample

StringBuilder sb = new StringBuilder();
sb.append(filename + "/");

vs.

StringBuilder sb = new StringBuilder();
sb.append(filename).append("/");

Java Solutions


Solution 1 - Java

You have to balance readability with functionality.

Let's say you have the following:

String str = "foo";
str += "bar";
if(baz) str += "baz";

This will create 2 string builders (where you only need 1, really) plus an additional string object for the interim. You would be more efficient if you went:

StringBuilder strBuilder = new StringBuilder("foo");
strBuilder.append("bar");
if(baz) strBuilder.append("baz");
String str = strBuilder.toString();

But as a matter of style, I think the first one looks just fine. The performance benefit of a single object creation seems very minimal to me. Now, if instead of 3 strings, you had 10, or 20, or 100, I would say the performance outweighs the style. If it was in a loop, for sure I'd use the string builder, but I think just a couple strings is fine to do the 'sloppy' way to make the code look cleaner. But... this has a very dangerous trap lurking in it! Read on below (pause to build suspense... dun dun dunnnn)

There are those who say to always use the explicit string builder. One rationale is that your code will continue to grow, and it will usually do so in the same manner as it is already (i.e. they won't take the time to refactor.) So you end up with those 10 or 20 statements each creating their own builder when you don't need to. So to prevent this from the start, they say always use an explicit builder.

So while in your example, it's not going to be particularly faster, when someone in the future decides they want a file extension on the end, or something like that, if they continue to use string concatenation instead of a StringBuilder, they're going to run into performance problems eventually.

We also need to think about the future. Let's say you were making Java code back in JDK 1.1 and you had the following method:

public String concat(String s1, String s2, String s3) {
    return s1 + s2 + s3;
}

At that time, it would have been slow because StringBuilder didn't exist.

Then in JDK 1.3 you decided to make it faster by using StringBuffer (StringBuilder still doesn't exist yet). You do this:

public String concat(String s1, String s2, String s3) {
    StringBuffer sb = new StringBuffer();
    sb.append(s1);
    sb.append(s2);
    sb.append(s3);
    return sb.toString();
}

It gets a lot faster. Awesome!

Now JDK 1.5 comes out, and with it comes StringBuilder (which is faster than StringBuffer) and the automatic transation of

return s1 + s2 + s3;

to

return new StringBuilder().append(s1).append(s2).append(s3).toString();

But you don't get this performance benefit because you're using StringBuffer explicitly. So by being smart, you have caused a performance hit when Java got smarter than you. So you have to keep in mind that there are things out there you won't think of.

Solution 2 - Java

Well, your first example is essentially translated by the compiler into something along the lines:

StringBuilder sb = new StringBuilder();
sb.append(new StringBuilder().append(filename).append("/").toString());

so yes, there is a certain inefficiency here. However, whether it really matters in your program is a different question. Aside from being questionable style (hint: subjective), it usually only matters, if you are doing this in a tight loop.

Solution 3 - Java

None of the answers so far explicitly address the specific case that hint is for. It's not saying to always use StringBuilder#append instead of concatenation. But, if you're already using a StringBuilder, it doesn't make sense to mix in concatenation, because it creates a redundant StringBuilder (See Dirk's answer) and an unnecessary temporary String instance.

Several answers already discuss why the suggested way is more efficient, but the main point is, if you already have a StringBuilder instance, just call append on it. It's just as readable (in my opinion, and apparently whoever wrote the NetBeans hint) since you're calling append anyway, and it's a little more efficient.

Solution 4 - Java

It's only more efficient if you are using lots of concatenation and really long strings. For general-use, such as creating a filename in your example, any string concatenation is just fine and more readable.

At any rate, this part of your application is unlikely to be the performance bottleneck.

Solution 5 - Java

Theoretically, yes. Because String objects are immutable: once constructed they cannot be changed anymore. So using "+" (concatenation) basically creates a new object each time.

Practically no. The compiler is clever enough to replace all your "+" with StringBuilder appendings.

For a more detailed explanation: http://kaioa.com/node/59

PS: Netbeans??? Come on!

Solution 6 - Java

A concat of two strings is faster using this function.

However, if you have multiple strings or different data type, you should use a StringBuilder either explicitly or implicitly. Using a + with Strings is using a StringBuilder implicitly.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMarek SeberaView Question on Stackoverflow
Solution 1 - JavacorsiKaView Answer on Stackoverflow
Solution 2 - JavaDirkView Answer on Stackoverflow
Solution 3 - JavaMatthew CrumleyView Answer on Stackoverflow
Solution 4 - JavamellamokbView Answer on Stackoverflow
Solution 5 - JavaGuillaumeView Answer on Stackoverflow
Solution 6 - JavaPeter LawreyView Answer on Stackoverflow