Someone told me it's more efficient to use StringBuffer
to concatenate strings in Java than to use the +
operator for String
s. What happens under the hood when you do that? What does StringBuffer
do differently?
相关问题
- Delete Messages from a Topic in Apache Kafka
- Jackson Deserialization not calling deserialize on
- How to maintain order of key-value in DataFrame sa
- StackExchange API - Deserialize Date in JSON Respo
- Difference between Types.INTEGER and Types.NULL in
As said, the String object is ummutable, meaning once it is created (see below) it cannot be changed.
So when you attempt to concanate String objects, the value of those objects are taken and put into a new String object.
If you instead use the StringBuffer, which IS mutable, you continually add the values to an internal list of char (primitives), which can be extended or truncated to fit the value needed. No new objects are created, only new char's are created/removed when needed to hold the values.
For simple concatenations like:
It is rather pointless to use
StringBuffer
- as jodonnell pointed out it will be smartly translated into:BUT it is very unperformant to concatenate strings in a loop, like:
Using string in this loop will generate 10 intermediate string objects in memory: "0", "01", "012" and so on. While writing the same using
StringBuffer
you simply update some internal buffer ofStringBuffer
and you do not create those intermediate string objects that you do not need:Actually for the example above you should use
StringBuilder
(introduced in Java 1.5) instead ofStringBuffer
-StringBuffer
is little heavier as all its methods are synchronized.Under the hood, it actually creates and appends to a StringBuffer, calling toString() on the result. So it actually doesn't matter which you use anymore.
So
becomes
That's true for a bunch of inlined appends within a single statement. If you build your string over the course of multiple statements, then you're wasting memory and a StringBuffer or StringBuilder is your better choice.
I think that given jdk1.5 (or greater) and your concatenation is thread-safe you should use StringBuilder instead of StringBuffer http://java4ever.blogspot.com/2007/03/string-vs-stringbuffer-vs-stringbuilder.html As for the gains in speed: http://www.about280.com/stringtest.html
Personally I'd code for readability, so unless you find that string concatenation makes your code considerably slower, stay with whichever method makes your code more readable.
Java turns string1 + string2 into a StringBuffer construct, append(), and toString(). This makes sense.
However, in Java 1.4 and earlier, it would do this for each + operator in the statement separately. This meant that doing a + b + c would result in two StringBuffer constructs with two toString() calls. If you had a long string of concats, it would turn into a real mess. Doing it yourself meant you could control this and do it properly.
Java 5.0 and above seem to do it more sensibly, so it's less of a problem and is certainly less verbose.
In some cases this is obsolete due to optimisations performed by the compiler, but the general issue is that code like:
will act as below (each step being the next loop iteration):
As you can see, each iteration is having to copy one more character, resulting in us performing 1+2+3+4+5+...+N operations each loop. This is an O(n^2) operation. If however we knew in advance that we only needed N characters, we could do it in a single allocation, with copy of just N characters from the strings we were using - a mere O(n) operation.
StringBuffer/StringBuilder avoid this because they are mutable, and so do not need to keep copying the same data over and over (so long as there is space to copy into in their internal buffer). They avoid performing an allocation and copy proportional to the number of appends done by over-allocing their buffer by a proportion of its current size, giving amortized O(1) appending.
However its worth noting that often the compiler will be able to optimise code into StringBuilder style (or better - since it can perform constant folding etc.) automatically.