Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance and simplicity tradeoffs between String, StringBuffer, and StringBuilder

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:

  1. 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.

  2. 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.)

like image 900
santiagobasulto Avatar asked Mar 26 '11 15:03

santiagobasulto


People also ask

Which is faster string or StringBuilder or StringBuffer?

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.

Which is better in performance string or 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.

How much faster is StringBuilder than StringBuffer?

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.

Why StringBuffer is slower than StringBuilder?

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.


2 Answers

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:

  • Use string when you don't want to perform manipulations, and want to be sure nothing else will
  • Use StringBuilder to perform manipulation, usually over a short period
  • Avoid StringBuffer 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.
like image 144
Jon Skeet Avatar answered Sep 30 '22 08:09

Jon Skeet


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.

like image 30
Ernest Friedman-Hill Avatar answered Sep 30 '22 08:09

Ernest Friedman-Hill