Have you ever thought about the implications of this change in the Java Programming Language?
The String class was conceived as an immutable class (and this decision was intentionally thought-out). But String concatenation is really slow, I've benchmarked it myself. So the StringBuffer was born. Really great class, synchronized and really fast. But some people were not happy with the performance cost of some synchronized blocks, and the StringBuilder was introduced.
But, when using String to concatenate not too many objects, the immutability of the class makes it a really natural way to achieve thread-safety. I can understand the use of StringBuffer when we want to manage several Strings. But, here is my first question:
If you have, say, 10 or fewer strings that you want to append, for example, would you trade simplicity for just some milliseconds in execution time?
I've benchmarked StringBuilder too. It is more efficient than StringBuffer (just a 10% improvement). But, if in your single-threaded program you're using StringBuilder, what happens if you sometimes want to change the design to use several threads? You have to change every instance of StringBuilder, and if you forget one, you'll have some weird effect (given the race condition that may arise) that can be produced.
In this situation, would you trade performance for hours of debugging?
Ok, that's all. Beyond the simple question (StringBuffer is more efficient than "+" and thread-safe, and StringBuilder is faster than StringBuffer but no thread-safe) I would like to know when to use them.
(Important: I know the differences between them; this is a question related to the architecture of the platform and some design decisions.)
String is immutable whereas StringBuffer and StringBuilder are mutable classes. StringBuffer is thread-safe and synchronized whereas StringBuilder is not. That's why StringBuilder is faster than StringBuffer.
The StringBuffer class is used to represent characters that can be modified. The significant performance difference between these two classes is that StringBuffer is faster than String when performing simple concatenations. In String manipulation code, character strings are routinely concatenated.
Speed: StringBuffer is actually two to three times slower than StringBuilder . The reason behind this is StringBuffer synchronization - only allowing 1 thread to execute on an object at a time results in much slower code execution.
Because StringBuffer methods are synchronized whereas StringBuilder methods are not, there is a speed difference. StringBuffer is more secure to use than StringBuilder, but it is also slower due to the additional synchronization mechanisms.
Just a comment about your "StringBuilders and threads" remark: even in multi-threaded programs, it's very rare to want to build up a string across multiple threads. Typically, each thread will have some set of data and create a string from that, often by concatenating multiple strings together. They'll then convert that StringBuilder
to a string, and that string can be safely shared among threads.
I don't think I've ever seen a bug due to a StringBuilder
being shared between threads.
Personally I wish StringBuffer
didn't exist - it was in the "let's synchronize everything" phase of Java, leading to Vector
and Hashtable
which have been almost obsoleted by the unsynchronized ArrayList
and HashMap
classes from Java 2. It just took a little while long for the unsynchronized equivalent of StringBuffer
to arrive.
So basically:
StringBuilder
to perform manipulation, usually over a short periodStringBuffer
unless you really, really need it - and as I say, I can't remember ever seeing a situation where I'd use StringBuffer
instead of StringBuilder
, when both are available.StringBuffer was in Java 1.0; it was not any kind of a reaction to slowness or immutability. It's also not in any way faster or better than string concatenation; in fact, the Java compiler compiles
String s1 = s2 + s3;
into something like
String s1 = new StringBuilder(s2).append(s3).toString();
If you don't believe me, try it yourself with a disassembler (javap -c, for example.)
The thing about "StringBuffer is faster than concatenation" refers to repeated concatenation. In that case explicitly creating yoir own StringBuffer and using it repeatedly performs better than letting the compiler create many of them.
StringBuilder was introduced in Java 5 for performance reasons, as you say. The reason it makes sense is that StringBuffer/Builder are virtually never shared outside of the method that creates them: 99% of their usage is something like the above, where they're created, used to append a few strings together, then discarded.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With