63

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("/");
Marek Sebera
  • 39,650
  • 37
  • 158
  • 244
  • Check out this interesting read: http://www.precisejava.com/javaperf/j2se/StringAndStringBuffer.htm – Zaki Sep 28 '11 at 16:18
  • 1
    @Zaki: Those benchmarks aren't really all that useful in practical terms. What's more useful is profiling your application to see if it really does have a performance bottleneck. And choosing the appropriate algorithms and data structures for your particular use case. – mellamokb Sep 28 '11 at 16:23

6 Answers6

85

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.

corsiKa
  • 81,495
  • 25
  • 153
  • 204
  • @corsiKa : My loop runs 16 times and this is what I am doinf in the loop - str+=som_value. Mine is jdk1.6. So should I use StringBuilder or not. – Ashwin Nov 17 '12 at 06:13
  • @Ashwin I would use StringBuilder there, personally. Is it necessary? I guess it depends on how often the loop gets run. If you're building the output of a hash, then you can expect to do that a lot. Definitely speed it up. If you're building the title of your program and it only gets called once, probably not such a big deal. – corsiKa Nov 20 '12 at 15:24
12

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.

Dirk
  • 30,623
  • 8
  • 82
  • 102
  • Is string concatenation actually done using a `StringBuilder`? It would seem much more sensible to have `String` include a constructor that accepts two strings and concatenates them (possibly also have versions for 3-4 strings, and one that takes a `String[]`). Given the strings to be concatenated, one could add their lengths before allocating space for the result's backing store, and thus allocate precisely the right amount of space in one go. It would seem crazy for the compiler not to do that. – supercat Dec 06 '13 at 17:25
7

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.

Community
  • 1
  • 1
Matthew Crumley
  • 101,441
  • 24
  • 103
  • 129
  • 1
    There are potentially some cases where doing the concatenation first would be beneficial; most of these are scenarios where, if strings had some random variations in their lengths, the probability of pre-concatenation being more efficient would be pretty low, but with some particular combinations of string lengths it might "win" every time. If the first `Append` would expand the `StringBuilder`/`StringBuffer` to a size insufficient to accommodate the second, the extra allocation caused by the concatenation could be less expensive than that used by the SB. A rare scenario, but possible. – supercat Dec 06 '13 at 17:32
  • @supercat That's an interesting point, and a good example of why you should always measure when you're optimizing code (and use representative data). – Matthew Crumley Dec 06 '13 at 18:07
  • 2
    My own preference would be to resort to my primary rule: "do what makes sense". In most cases there's not apt to be a huge performance difference either way, so favor the concatenation when it's clearer and unlikely to noticeably affect performance. In cases where multiple concatenations must occur in different statements, I prefer `StringBuilder`, but when they can occur in one expression I prefer that. Unless strings are big, legibility should be a higher priority than performance. – supercat Dec 06 '13 at 19:24
2

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.

mellamokb
  • 56,094
  • 12
  • 110
  • 136
2

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!

Guillaume
  • 22,694
  • 14
  • 56
  • 70
  • `Come on!` ? What would you recommend then? – Marek Sebera Sep 28 '11 at 16:40
  • Your second sentence implies they are all put into one StringBuilder. This is inaccurate. If you have `String s = "a" + "b"; s += "c";` you get 2 string builders, not 1. – corsiKa Sep 28 '11 at 16:46
  • 1
    I would recommend IntelliJ. Worked with eclipse from 2003 till 1012, then switched. BIG performace increase. On topic: indeed string concat these days. – Lawrence Sep 17 '13 at 13:29
  • Same here. I was a big fan of Eclipse, until I tried IntelliJ "only for a couple of days" due to constant nagging from my colleagues. I never looked back. – Guillaume Sep 17 '13 at 14:10
2

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.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130