Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

StringBuilder dimensions 3

Status
Not open for further replies.

1DMF

Programmer
Jan 18, 2005
8,795
GB
Hi,

Can someone explain to me why StringBuilder is auto sized to 16 when initialised?

All other Arrays & Collections are either zero size, or fixed size. (capacity)

The collections framework where size can be dynamic is always zero length to start with and grows as the elements are added.

Why is StringBuilder sized in this way?



"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!"

Google Rank Extractor -> Perl beta with FusionCharts
 
That doesn't seem to happen to me.

Code:
moxie - axtell - ~ > cat Test.java
public class Test {

public Test(){
StringBuilder b = new StringBuilder();
System.out.println(b.length());
b.setLength(12);
System.out.println(b.length());
}

public static void main(String args[]){
Test t = new Test();
}
}

moxie - axtell - ~ > javac Test.java
moxie - axtell - ~ > java Test
0
12
moxie - axtell - ~ >

Am I missing something?

-----------------------------------------
I cannot be bought. Find leasing information at
 
Well my course book says...
StringBuilder() initialises an 'empty' StringBuilder object with the potential to store 16 characters.

I asked a tutor and they couldn't answer me why it's 16 in capacity to start with, and even said if I found the answer , please let them know!

It's just a curiosity thing that's all. If you add more than 16chars, it auto resizes itself with another 16 and so on. why doesn't it just grow as its contents grows and start as this array would
Code:
String[] myArray = new String[1];

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!"

Google Rank Extractor -> Perl beta with FusionCharts
 
Oh ok. StringBuilder and StringBuffer will both initialize to hold 16 characters by default. When the need more, they extend (get copied to a new character array of a larger size) to the larger of the two: double their size before needing to be extended, or the length of the array before being extending plus the length of the string to append to the array. I'm not entirely sure why they decided to start at 16, but my guess is for performance reasons. If it started off at zero or one it could need to be extended several times after the first few appends. By starting it at 16 that might be avoided, thus improving performance. I don't think other collections are likely to grow as fast as a StringBuilder would. But thats just a guess.

-----------------------------------------
I cannot be bought. Find leasing information at
 
I don't think I invent anything.
ref
These are two of the constructors (amongst four of them)
-quote-[tt]
StringBuilder()
Constructs a string builder with no characters in it and an initial capacity of 16 characters.
StringBuilder(int capacity)
Constructs a string builder with no characters in it and an initial capacity specified by the capacity argument.
[/tt]
-unquote-

The proper verification is using the capacity() method with constructor StringBuild().
[tt]
StringBuilder b = new StringBuilder();
System.out.println(b.capacity());
[/tt]
Horstmann and Cornell's <Core Java> vol.1 (8th ed) has this to say:
-quote-[tt]
Occasionally, you need to build up stings from shorter strings, such as keystrokes or words from a file. It would be inefficient to use string concatination for this purpose. Every time you concatinate strings, a new String object is constructed. This is time consuming and it wastes memory. Use StingBuilder class avoids this problem.
[/tt]-unquote-
 
hey tsuji,

I appreaciate why there is the StringBuilder class, and the issue with doing...
Code:
String aStr = "";
for (int i = 0; i < 10000; i++)
{
   aStr += "*";
}

That will create 10,0001 objects of class String and StringBuilder is to stop this inefficiency.

Are you saying that if StringBuilder started at capacity zero or one and then added room as needed a char at a time, it would be just as inefficient as the code above?

As StringBuilder does it in 16 char chunks, does that mean behind the scenes using StringBuilder for the above code it would still create 625 objects?

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!"

Google Rank Extractor -> Perl beta with FusionCharts
 
>As StringBuilder does it in 16 char chunks, does that mean behind the scenes using StringBuilder for the above code it would still create 625 objects?
No. Again I don't invent anything. I think the engine's internal working has a good among of guess-work to strive for optimization. Inspect the result of this.
[tt]
StringBuilder b = new StringBuilder();
System.out.println(b.length());
System.out.println("capacity:" + b.capacity());
b.append("this is 22 characters.");
System.out.println("capacity:" + b.capacity());
System.out.println("length:"+b.length());
b.append("this is 22 characters.");
System.out.println("capacity:" + b.capacity());
System.out.println("length:"+b.length());
b.append("this is 22 characters.");
System.out.println("capacity:" + b.capacity());
System.out.println("length:"+b.length());
b.append("this is 22 characters.");
System.out.println("capacity:" + b.capacity());
System.out.println("length:"+b.length());
[/tt]
It is not as simplistic as one would speculate with 16 chars or 32 bytes or whatever (or any number of initial capacity inputted in the initialization).
 
So the bottom line is no-one knows why it is 16 , if it has no bearing on optimisation!

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!"

Google Rank Extractor -> Perl beta with FusionCharts
 
No, it should only create 11 objects, with the first one 16 characters and every other one twice the size of the one before.
16,32,64,128, etc.

-----------------------------------------
I cannot be bought. Find leasing information at
 
>So the bottom line is no-one knows why it is 16 , if it has no bearing on optimisation!
People designing the spec need to start somewhere, no? And some multiple of 8 seems to be natural in the memory management (addressing...) I think that's all it takes for a decision (a tradeoff among parsimony of memory use, frequency of extending capacity and easier memory addressing.)
 
>with the first one 16 characters and every other one twice the size of the one before.
16,32,64,128, etc.

The demonstration I posted shows something more subtle than that. This is what I get (with the first two lines amended to fall inline with the rest).
[tt]
capacity:16
length:0
capacity:34
length:22
capacity:70
length:44
capacity:70
length:66
capacity:142
length:88
[/tt]
 
Not subtle. Like I explained earlier, except I was off by one. Its (x+1)*2, where x was the previous value.

-----------------------------------------
I cannot be bought. Find leasing information at
 
Not very subtle, indeed, even simplistic.
 
After looking up "subtle" in the dictionary, I still don't get the idea, so I will post my own reply.

No one should care about the default initialization size, as it should never be used. Performance best practises says that you need to set the initial size.

I remember the old StringBuffer concatenation as a performance improvement source. Well, it's useless if you don't initialize it to the expected size, because the size-increasing operation is time-consumung by definition.

An old article about this.

Cheers,
Dian
 
so Dian is

Code:
StringBuilder b = new StringBuilder(1);

better than just using
Code:
StringBuilder b = new StringBuilder();

or is that still going to have the expenetial growth as you add to it.

What your saying is , ending up with
capacity:142
length:88
is bad, when it would have been better to guess you wouldn't need more than 100 for example
Code:
StringBuilder b = new StringBuilder(100);

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!"

Google Rank Extractor -> Perl beta with FusionCharts
 
>But you can estimate it
I do not disagree, sure.

>No one should care about the default initialization size
Why should one say something like that is beyond me.
 
No one should care about the default initialization sizeWhy should one say something like that is beyond me.
Well as I mentioned the Open University made a point of mentioning it in the course book, hence me wondering why it's 16.

But it does make me wonder how this can be performance enhancing when..

if you don't know what size you need it exponetially grows far greater than required.

Is that really more eficient than having a load of dead objects of string, which may have already been garbage collected.

If garbage collection happens soon after the String concatenation, then isn't that more efficient than having a StringBuilder object far bigger than is required?

I know you cannot force garbage collection, but wouldn't it be betterif you could? Surely controlled garbage collection is far more efficient than the current situation or StringBuilder?



"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!"

Google Rank Extractor -> Perl beta with FusionCharts
 
No one should care about the default initialization sizeWhy should one say something like that is beyond me.
Well as I mentioned the Open University made a point of mentioning it in the course book, hence me wondering why it's 16.

But it does make me wonder how this can be performance enhancing when..

if you don't know what size you need it exponetially grows far greater than required.

Is that really more eficient than having a load of dead objects of string, which may have already been garbage collected.

If garbage collection happens soon after the String concatenation, then isn't that more efficient than having a StringBuilder object far bigger than is required?

I know you cannot force garbage collection, but wouldn't it be better if you could? Surely controlled garbage collection is far more efficient than the current situation or StringBuilder?



"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!"

Google Rank Extractor -> Perl beta with FusionCharts
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top