Subject: Re: StringBuffer & String and the shared paradigm... WHY?
Date: Tue, 17 Oct 2000 04:43:17 GMT
From: [email protected] (Dirk Bosmans)
Organization: Customer of TijdNet
Newsgroups: comp.lang.java.programmer

I'm reacting to following parts of "Johan Compagner" <joco@wxs.nl>'s article in
comp.lang.java.programmer on Mon, 16 Oct 2000 09:51:44 +02006

> Hi,
>
>
I don't know how many of you guys really knows how String and StringBuffer are working together (through the toString()) but it goes
> as this:
>
>
When you want a String out of StringBuffer: StringBuffer.toString() is called that one calls the String(StringBuffer) constructor of
> String.
> There the Char array of the StringBuffer is set as the Char array of string offset = 0, count = stringbuffer.length()
> This means that you can have a (worse case) 100% to big char array!
> For example the default size of StringBuffer char array = 16 now you add 17 chars to it: then the char array is 16*2+1 = 33.
> And then you do toString() so the String of that 17 chars has its 17 chars in a 33 char big array! That's about 100% too much!
> So let's say that the average is the waste if using StringBuffer that still means that of all the Strings that are created with a
> StringBuffer has an average of 50% waste!
>
>
After that there are 2 choices: The StringBuffer is used again, or the StringBuffer is discarded:
>
>
Used again:
> Then the StringBuffer's array is copied into a new as big as the current one
> So you have suddenly 2 big arrays! So in the above example you add 1 char and call to string again: Now you have a second string: 18
> chars in a 33 chars array.
> So when a StringBuffer is used again this approach is horrible must better is the way of when you call toString() the String makes a
> array exactly the size needed and copies the used portion of the array of the StringBuffer into that. After that the StringBuffer
> can still use it's own char array and the String has a waste of 0%.
>
>
So when using a stringbuffer after calling toString() the shared approach is just wrong.
> But if you don't use it again has the shared approach advantages?
> The String is still with an average of 50% to big! The one advantage is see is that you don't have to make a new array and then copy
> the section.
> But does that justify an average of 50% to large array's in all the strings that are made by a StringBuffer (so also the one of str
> += "test";)??
>
>
Happily there is a choice when you are working with a StringBuffer:
> String str = stringBuffer.substring(0,stringBuffer.length());
> This copies the array into a new one and the stringbuffer keeps the current.
>
>
Do I miss something?
>
>
Johan Compagner
> J-COM
>
>

There is also a similar memory danger with String.subString() in some cases.

I had a program that was reading lots of (sometimes large) text files into one
String each, and then take a substring of a few words, keeping no reference to
the original file-in-a-string. After some limit tests, memory problems came in
production. It appeared that a String.subString() keeps the original char[]
reference, and just sets its offset and length to some substring within that
char[] (which saves memory in most common cases, I guess). Solution was the
sequence
        String myWords = new String(fileInAString.subString(i, j));
which allocates a new char[] and copies only the necessary chars into it.

Greetings,
Dirk Bosmans

http://users.belgacombusiness.net/arci/
- Applicet Framework: turns Applets into Applications
- ArciMath BigDecimal: now with BigDecimalFormat