3

In the past, I have been lead to believe that you should use StringBuilder and append(String) when building a string with variables, as opposed to string += split[i]. In what cases is this accurate? I ask because normally, if I was to write the following:

String[] split = args; // command line arguments or whatever
String myString = "";
for (int i = 0; i < split.length; i++) {
    myString += split[i];
}

I am told by my IDE that it should be converted to use a StringBuilder instead. However, writing something like this:

StringBuilder build = new StringBuilder();
build.append("the ").append(build.toString()).append(" is bad").append(randomvar);
build.toString();

IntelliJ actually lists as a performance issue using a StringBuilder when I should be using a String. The fact that it's listed as a performance issue would indicate it could actually cause problems as opposed to just being a tiny bit slower.

I did notice that the first example is a loop and the second isn't - is a StringBuilder recommended for lots of concatenations but normal concatenation is better for non-looping situations (this also means in a loop the operator += would be used, whereas outside of a loop it could be "the " + build.toString() + " is bad" + randomVar - is += the problem as opposed to +?)

OllieStanley
  • 712
  • 7
  • 25
  • Wouldn't this be easily testable? Like putting a for loop for 10000 appends vs + operations. If the strings are known, then + can be optimized by the compiler. – user1071777 Aug 25 '14 at 18:52
  • The `+` operator will always be more efficient when the entire operation consists of concatenating exactly two strings. – cdhowie Aug 25 '14 at 18:52
  • I would argue it isn't a duplicate because this is more on the differences between it being in a loop and not being in a loop than anything else. – OllieStanley Aug 25 '14 at 18:56
  • @DziNeIT it's a duplicate. Just check the answers on those questions, where concatenation inside a loop is covered as well. – Luiggi Mendoza Aug 25 '14 at 18:57
  • @cdhowie OK - and if it isn't going to be faster the compiler will optimize it anyway, so normally unless it's a loop the + operator should be used, right? – OllieStanley Aug 25 '14 at 18:58
  • @DziNeIT Generally yes. – cdhowie Aug 25 '14 at 18:58
  • @LUiggi there is information on this page that there isn't on those pages, so you're wrong – OllieStanley Aug 25 '14 at 18:59
  • @DziNeIT no. When in a loop, use `StringBuilder`. More info here: [In what cases String is usefull than StringBuffer & StringBuilder](http://stackoverflow.com/a/24580753/1065197) – Luiggi Mendoza Aug 25 '14 at 18:59
  • "Premature optimization is the root of all evil"... `+` and `+=` are easier to read, in my opinion, and that's the controlling factor 99% of the time. If your IDE has an objection, try to find an IDE option to make it keep its opinions to itself. – ajb Aug 25 '14 at 19:01
  • 1
    @ajb this is not a case of premature optimization... – Luiggi Mendoza Aug 25 '14 at 19:01
  • @ajb It is not premature optimization, it is common sense to use `StringBuilder#append` if you are creating String using loop instead of `+=`. – Pshemo Aug 25 '14 at 19:04

4 Answers4

10

String concatenations are converted into calls to StringBuilder.append() behind the scenes.

String literal concatenations are (or at least can be) converted to individual String literals.

You're presumably using a String variable (not just two literals) inside the loop, so Java can't just replace that with a literal; it has to use a StringBuilder. That's why doing String concatenations in a loop should be done using a single StringBuilder, otherwise Java ends up creating another instance of StringBuilder every time the loop iterates.

On the other hand, something like this:

String animals = "cats " + "dogs " + "lizards ";

Will (or can be) replaced (by Java, not you) with a single String literal, so using a StringBuilder is actually counter-productive.

Kevin Workman
  • 41,537
  • 9
  • 68
  • 107
3

Beginning in java 1.5, the String + operator is translated into calls to StringBuilder.

In your example, the loop should be slower because the + operator creates a new StringBuilder instance each time through the loop.

DwB
  • 37,124
  • 11
  • 56
  • 82
  • This answer buries the lede a bit. The `+` operator is worse because it creates a new `StringBuilder` each time, _and that's an O(N) operation_. When you do it in a loop, it means the whole thing is O(N^2). – yshavit Aug 25 '14 at 18:58
1

The compiler will actually turn them both into the same form before compiling so neither will result in any performance difference. In this scenario you want to go with the shortest and most readable method available to you.

"An implementation may choose to perform conversion and concatenation in one step to avoid creating and then discarding an intermediate String object. To increase the performance of repeated string concatenation, a Java compiler may use the StringBuffer class or a similar technique to reduce the number of intermediate String objects that are created by evaluation of an expression.

For primitive types, an implementation may also optimize away the creation of a wrapper object by converting directly from a primitive type to a string."

Source: http://docs.oracle.com/javase/specs/jls/se5.0/html/expressions.html#15.18.1.2

Andrew
  • 995
  • 6
  • 10
  • Not in the first case, at least the compiler will not create a `StringBuilder` that outlives the loop -- it's not that smart. The first case should still be manually optimized. – cdhowie Aug 25 '14 at 18:54
0

For little concats you can use the + operator with none issue. StringBuffer is indicated when we have large strings to be concatened, so with this class you can save memory and processor's time as well.

You can make a test trying to concat 1 million of words using + operator, and run the same teste using StringBuffer to see the different by yourself.

vinibarr
  • 500
  • 3
  • 5