-2

This is a follow up question to :
Concatenation by += slower than that by using StringBuilder()
where I found out that string1+=string2 is much slower than string1.append(string2) where string1 is now a StringBuilder

My follow up question:
What does StringBuilder internally do, that makes it much faster?

Community
  • 1
  • 1
sanjeev mk
  • 4,276
  • 6
  • 44
  • 69
  • 4
    Microbenchmarks are not reliable measures of performance. You can always go read the Java source code if you really want to know. – Elliott Frisch Aug 10 '14 at 20:40
  • 1
    possible duplicate of [Comparison of String and StringBuilder manipulation in terms of Memory usage](http://stackoverflow.com/questions/20429442/comparison-of-string-and-stringbuilder-manipulation-in-terms-of-memory-usage) – jmiserez Aug 10 '14 at 20:44
  • 1
    look at this one question I think it will give you overview of internal implementation and probably why it is faster: http://stackoverflow.com/questions/8011338/how-is-stringbuffer-implementing-append-function-without-creating-2-objects – LeTex Aug 10 '14 at 20:48

3 Answers3

4
string1 += string2 

is basically equivalent to

StringBuilder b = new StringBuilder(string1);
b.append(string2);
string1 = b.toString();

or to

StringBuilder b = new StringBuilder();
b.append(string1);
b.append(string2);
string1 = b.toString();

depending on the compiler (thanks @JonK)

So, if you concatenate using += in a loop, you end up creating a lot of temporary String and StringBuilder instances, larger and larger at each iteration, and you also force the garbage collector to collect all those temporary objects.

Whereas if you use a StringBuilder, you create a single object, containing a single buffer that contains everything, until you end the loop and transform the buffer to a String. The buffer can become too small, but the algorithm then creates a new one that that is twice the size of the original, which means that even if you append thousands of strings, the number of buffers created is small. Much smaller than the number of String and StringBuilder instancs needed by +=.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • 1
    This is true of the Eclipse compiler, but the Oracle compiler will always use the no-args StringBuilder constructor, and will call append twice in this instance. – JonK Aug 10 '14 at 20:48
  • Correct. The point remains, though. Whatever the compiler used, it generates lots of temporary objects. – JB Nizet Aug 10 '14 at 20:52
  • @JBNizet some temporary objects, but not more than it would if you use StringBuilder directly (as long as you can fit all the string building in one expression). – eckes Aug 24 '14 at 01:00
  • @eckes: you missed the "in a loop" part. – JB Nizet Aug 24 '14 at 06:09
2

StringBuilder is not faster than "+=", it is only faster when used in a loop or if you need to concatenate multiple parts (because the intermediate result does not need to create a string object and throw it away).

In fact when you only need to add a single suffix outside a loop, += is not only easier to read, but also can be optimized better.

I did a JMH test to back up my statement, here are the results which show, that in a single-shot case stringbuilder and += (which internally does use SB as well) is nearly the same speed (with += having a slight advantage):

Benchmark                          (prefixLen)  Mode  Samples    Score  Score error  Units
n.e.j.StringConcat.plus                      0  avgt        5  121,327       17,461  ns/op
n.e.j.StringConcat.plus                     10  avgt        5  126,112       12,381  ns/op
n.e.j.StringConcat.plus                    100  avgt        5  181,492       17,012  ns/op
n.e.j.StringConcat.plusEquals                0  avgt        5  120,520        5,899  ns/op
n.e.j.StringConcat.plusEquals               10  avgt        5  131,687        7,651  ns/op
n.e.j.StringConcat.plusEquals              100  avgt        5  173,384        5,096  ns/op
n.e.j.StringConcat.stringBuffer              0  avgt        5  118,633        9,356  ns/op
n.e.j.StringConcat.stringBuffer             10  avgt        5  125,862       11,661  ns/op
n.e.j.StringConcat.stringBuffer            100  avgt        5  173,753        3,205  ns/op

(The numbers mean basically all 3 methods have the same performance, and please be aware this is not a very scientific approach for this kind of micro benchmark)

The code for that test is here: https://gist.github.com/ecki/5bcc3a4de669414401b6

And just to reiterate: yes StringBuffer is much more efficient of you need to to multiple concatenations to the same string, but when having only the need for a one-shot append I would prefer the + operator - not only for readability reasons.

eckes
  • 10,103
  • 1
  • 59
  • 71
-1

I know that StringBuilder uses a char array to store the characters. It is more efficient than String because that char array is resized every time it`s necessary. In case of string, if you have String a="foo"; String b='foo' and you make a=a+b; the older reference stored in a is dropped and it is created a new String object(String is imutable).

lucian.marcuta
  • 1,250
  • 1
  • 16
  • 29
  • NB: "resized every time its necesary" actually means: less often than concatenate is called (but at least once, this is why it is not faster for a single concatenation). – eckes Aug 10 '14 at 21:35