views:

473

answers:

11

Strings are immutable, meaning, once they have been created they cannot be changed.

So, does this mean that it would take more memory if you append things with += than if you created a StringBuffer and appended text to that?

If you use +=, you would create a new 'object' each time that has to be saved in the memory, wouldn't you?

+3  A: 

Yes. String is immutable. For occasional use, += is OK. If the += operation is intensive, you should turn to StringBuilder.

Benny
A: 

I think it relies on the GC to collect the memory with the abandoned string. So doing += with string builder will be definitely faster if you have a lot of operation on string manipulation. But it's shouldn't a problem for most cases.

Ted Lee
No += wouldn't be faster when you're doing alot of string manipulation, StringBuffer would be alot faster. You're right about the GC that will probably take care of all the abandoned String objects properly but there is still the cost of object creation..
NickDK
+1  A: 

Exactly. You should use a StringBuilder though if thread-safety isn't an issue.

As a side note: There might be several String objects using the same backing char[] - for instance whenever you use substring(), no new char[] will be created which makes using it quite efficient.

Additionally, compilers may do some optimization for you. For instance if you do

static final String FOO = "foo";
static final String BAR = "bar"; 

String getFoobar() {
  return FOO + BAR; // no string concatenation at runtime
}

I wouldn't be surprised if the compiler would use StringBuilder internally to optimize String concatenation where possible - if not already maybe in the future.

sfussenegger
A: 

Yes you would and that is exactly why you should use StringBuffer to concatenate alot of Strings.

Also note that since Java 5 you should also prefer StringBuilder most of the time. It's just some sort of unsynchronized StringBuffer.

NickDK
+1  A: 

But the garbage collector will end up freeing the old strings once there are no references to them

p__
Its not the garbage per se that is the problem. It is all of the character copying that kills you! Concatenating N by 1 character strings using `+=` copies `O(N^2)` characters.
Stephen C
I wouln't be that sure of it. Some Strings end up in Perm Space and there is no garbage collector for this area as far as i know of. A string object gets into the pool by using String.intern().
dz
If you’re calling `intern()` on a `String` that only exists in a loop and is not required outside of it you shouldn’t be coding at all.
Bombe
+5  A: 

In Java 5 or later, StringBuffer is thread safe, and so has some overhead that you shouldn't pay for unless you need it. StringBuilder has the same API but is not thread safe (i.e. you should only use it internal to a single thread).

Yes, if you are building up large strings, it is more efficient to use StringBuilder. It is probably not worth it to pass StringBuilder or StringBuffer around as part of your API. This is too confusing.

Kevin Peterson
StringBuffer has always been synchronized - they didn't make it synchronized for Java 5, that's just why they introduced StringBuilder.
Jon Skeet
That makes a lot more sense than what I previously thought. I noticed that the documentation changed from 1.4 to 5 and thread safe is now mentioned more prominently.
Kevin Peterson
+14  A: 

Yes, you will create a new object each time with +=. That doesn't mean it's always the wrong thing to do, however. It depends whether you want that value as a string, or whether you're just going to use it to build the string up further.

If you actually want the result of x + y as a string, then you might as well just use string concatenation. However, if you're really going to (say) loop round and append another string, and another, etc - only needing the result as a string at the very end, then StringBuffer/StringBuilder are the way to go. Indeed, looping is really where StringBuilder pays off over string concatenation - the performance difference for 5 or even 10 direct concatenations is going to be quite small, but for thousands it becomes a lot worse - basically because you get O(N2) complexity with concatenation vs O(N) complexity with StringBuilder.

In Java 5 and above, you should basically use StringBuilder - it's unsynchronized, but that's almost always okay; it's very rare to want to share one between threads.

I have an article on all of this which you might find useful.

Jon Skeet
+5  A: 

Rule of thumb is simple:

If you are running concatenations in a loop, don't use +=

If you are not running concatenations in a loop, using += simply does not matter. (Unless a performance critical application

Kyle Rozendo
A: 

You're right that Strings are immutable, so if you're trying to conserve memory while doing a lot of string concatenation, you should use StringBuilder rather than +=.

However, you may not mind. Programs are written for their human readers, so you can go with clarity. If it's important that you optimize, you should profile first. Unless your program is very heavily weighted toward string activity, there will probably be other bottlenecks.

JXG
+4  A: 

I agree with all the answers posted above, but it will help you a little bit to understand more about the way Java is implemented. The JVM uses StringBuffers internally to compile the String + operator (From the StringBuffer Javadoc):

String buffers are used by the compiler to implement the binary string concatenation operator +. For example, the code:

     x = "a" + 4 + "c"

is compiled to the equivalent of:

     x = new StringBuffer().append("a").append(4).append("c")
                           .toString()

Likewise, x += "some new string" is equivalent to x = x + "some new string". Do you see where I'm going with this?

If you are doing a lot of String concatenations, using StringBuffer will increase your performance, but if you're only doing a couple of simple String concatenations, the Java compiler will probably optimize it for you, and you won't notice a difference in performance

iWerner
A: 

No

It will not use more memory. Yes, new objects are created, but the old ones are recycled. In the end, the amount of memory used is the same.

DigitalRoss