Wow! That was pretty comprehensive. Just one thing I'm not sure about
though:
You say that
out.print( "The value of variableX is " );
out.print( variableX );
out.println( "<BR>" );
involves 0 object creations... surely just doing out.print ("some string")
has to instantiate an object? Otherwise what gets passed to the function? I
didn't think that strings could just exist outside of an object, or am I
missing something there?
Cheers,
Ben
-----Original Message-----
From: Paul Philion [mailto:[EMAIL PROTECTED]]
Sent: Thursday, August 19, 1999 4:34 PM
To: [EMAIL PROTECTED]
Subject: Re: Preallocate space (StringBuffer vs. String)
Milt -
IM(ns)HO, the use of the out.print(), out.println() is the most efficient
(both for memory and time), but the most difficult to maintain. Let's look
at the different versions:
// version 1, String concat
out.println( "The value of variableX is " + variableX + "<BR>" );
is converted into
// version 1, String concat, converted by compiler
out.println( new StringBuffer( "The value of variableX is " ).append(
variableX ).append( "<BR>" ).toString() );
By my calculations that is 5 methods calls, including 1 object creation.
This is very similar to
// version 2, StringBuffer
StringBuffer buffer = new StringBuffer();
buffer.append( "The value of variableX is " );
buffer.append( variableX );
buffer.append( "<BR>" );
out.println( buffer.toString() );
In this specific case, they are about the same execution wise, but version 1
is preferable because of readability.
HOWEVER (that is a big however, notice) version 2 is preferable if there is
some sort of looping the is used to fill the buffer. This is *usually* the
case, as most output (esp. HTML output) is not so trivial. In the looping
case, the following happens:
// version 1, String concat
for ( int i = 1; i <= 10, i++ ) {
out.println( "The value of variableX is " + i + "<BR>" );
}
becomes
// version 1, String concat, converted by compiler
for ( int i = 1; i <= 10, i++ ) {
out.println( new StringBuffer( "The value of variableX is " ).append(
i ).append( "<BR>" ).toString() );
}
Which turns out to be 50 method calls, including 10 object instantiations.
*Lots* of garbage!
Thus, the following StringBuffer idiom becomes much more effective:
// version 2, StringBuffer
StringBuffer buffer = new StringBuffer();
for ( int i = 1; i <= 10, i++ ) {
buffer.append( "The value of variableX is " );
buffer.append( i );
buffer.append( "<BR>" );
}
out.println( buffer.toString() );
It has only 32 method calls and only 1 object creation.
Rule of thumb: Simple Strings, little output: use String concatenation.
Complex output, including loops: use StringBuffer.
But lets go a step farther and examine the "use println only" idiom:
// version 2, println only
out.print( "The value of variableX is " );
out.print( variableX );
out.println( "<BR>" );
3 method calls, 0 (zero) object creation. Good, better than versions 1 and
2. Looping:
// version 3, println only
for ( int i = 1; i <= 10, i++ ) {
out.print( "The value of variableX is " );
out.print( i );
out.println( "<BR>" );
}
30 method calls, 0 (zero) object creation. Even better than versions 1 and
2. So version 3 is more efficient than both versions 1 and 2 in all cases.
HOWEVER (note the big however again), version 3 is also more difficult to
maintain and less flexible.
Rule of thumb: Use version 3 only when execution speed and memory usage is a
critical part of the deliverable. OR, build a framework that hides the nasty
bits, perserves the efficiency and increases flexibility. For HTML, a good
template system can help with these goals.
Finally, my article about servlets offers a little more detail on this
subject:
http://www.javaworld.com/jw-12-1998/jw-12-servlethtml.html
Hope this helps,
- Paul Philion
[EMAIL PROTECTED]
Milt Epstein wrote:
> To turn this thread a bit, and connect it with some other recent
> discussion about the performance benefits of using StringBuffer's (and
> append) instead of String's (and concatenation), I've got a question
> or two. I can understand how performance is improved that way. But
> does that mean you should *always* use StringBuffers instead of
> Strings and concatenation? Because those are used all over the
> place.
>
> For example, suppose I do something as innocuous as:
>
> out.println("The value of variableX is " + variableX + "<BR>");
>
> Would it really be worth it to use a StringBuffer for what's being
> output there?
>
> Another alternative would be to use a combination of out.print's and
> out.println's, a la:
>
> out.print("The value of variableX is ");
> out.print(variableX);
> out.println("<BR>");
>
> This gets rid of the concatenation, but at the penalty of additional
> method calls.
>
> I don't want to go crazy with this, I'm just trying to get a handle on
> just how far to go with StringBuffer's. Thanks.
___________________________________________________________________________
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff SERVLET-INTEREST".
Archives: http://archives.java.sun.com/archives/servlet-interest.html
Resources: http://java.sun.com/products/servlet/external-resources.html
LISTSERV Help: http://www.lsoft.com/manuals/user/user.html
___________________________________________________________________________
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff SERVLET-INTEREST".
Archives: http://archives.java.sun.com/archives/servlet-interest.html
Resources: http://java.sun.com/products/servlet/external-resources.html
LISTSERV Help: http://www.lsoft.com/manuals/user/user.html