From: Tom Anderson on
On Tue, 22 Jul 2008, Mike Schilling wrote:

> Roedy Green wrote:
>> On Tue, 22 Jul 2008 17:46:21 +0100, Tom Anderson
>> <twic(a)urchin.earth.li> wrote, quoted or indirectly quoted someone
>> who
>> said :
>>
>>>> I stupidly did not benchmark before the changes.
>>>
>>> No, but you have the old version in source control, right?
>>
>> I used this method to optimise the initial sizes of the StringBuilders
>> used in the static macros program that expands the macros used to
>> generate the mindprod.com website. It does a great many StringBuilder.
>> appends, though it also does a fair bit of i/o as well, since it has to
>> read each file in the website. Here are the results:
>>
>> Effect of StringBuilder Optimising
>> Time Before Optimising Time After Optimising % improvement
>> Sun 27.5 sec 24 sec 13%
>> Jet 25 sec 22.5 sec 10%
>
> That is quite significant indeed. Thanks.

Yes, thanks. This is interesting stuff.

Roedy, how did you do the analysis? You showed us the routine which
detects wrong-sized buffers, but where do you call it from? Every time you
to a StringBuffer.toString()?

I'm wondering if a more convenient way would be to hack the StringBuffer
class itself. You can get the source code from the JDK, modify it, then
use -Xbootclasspath/p to get it loaded in place of the normal
StringBuffer.

You could alter the class to remember its initial size, then to log its
initial size and final number of characters in its toString, along with a
bit of stack trace to see where it's being used.

You could do other stuff too, like counting the number of times toString
gets called, then having a finalizer which looks at the number, and if
it's zero, logs the fact that the buffer was never toStringed. You could
probably think of other things to check too.

Er, and in the above, s/StringBuffer/StringBuilder/, as appropriate.

tom

--
We can only see a short distance ahead, but we can see plenty there that
needs to be done. -- Alan Turing
From: Roedy Green on
On Wed, 23 Jul 2008 14:35:44 +0100, Tom Anderson
<twic(a)urchin.earth.li> wrote, quoted or indirectly quoted someone who
said :

>
>Roedy, how did you do the analysis? You showed us the routine which
>detects wrong-sized buffers, but where do you call it from? Every time you
>to a StringBuffer.toString()?

I inserted a call just prior to StringBuffer.toString. This generated
output any time the actual size was outside my estimated range. I
then typically adjusted the range and the initial size. In a few
cases I put in code to precalculate the precise size such as this:

/**
* Display macro name and parms on error.
*
* @return parms as a human-readable string.
*/
private String showParms()
{
// macroName and parms may be null.
if ( macroName == null )
{
macroName = "?";
}

// get exact estimate of size of string we will build.
int estSize = " <!-- macro ".length()
+ macroName.length()
+ "\n".length();

if ( parms != null )
{
for ( String parm : parms )
{
estSize += " {".length() + parm.length() +
"}\n".length();
}
}
estSize += " -->".length();

final StringBuilder sb = new StringBuilder( estSize );

sb.append( " <!-- macro " );
sb.append( macroName );
sb.append( '\n' );
if ( parms != null )
{
for ( String parm : parms )
{
sb.append( " {" );
sb.append( parm );
sb.append( "}\n" );
}
}
sb.append( " -->" );
Tools.checkStringBuilderEstimate( sb, estSize, estSize );
return sb.toString();
}
--

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com