Ben -

Let's look at the details...

1) Does out.print() or out.println() create objects?

Effectively, no (rather, they don't need to though someone might implement them 
poorly)...

println() just calls print(), and print() just iterates over the characters in the 
String and write()s them. So for print()ing Strings, there is no need to create any 
objects.

print()ing an int (as in the looping examples below) requires calling 
Integer.toString(), which will create 2 objects (a small char array and a String). 
Note that *all* implementations below will make the same conversion eventually.

2) Does a literal String create any objects?

Well... Yes and no. Yes because a String object must be created, obviously. No, 
because that literal String object is effectively created by the compiler and it is 
statically interned before execution. So no additional overhead is incurred at runtime 
by a static String.

See the Java Language Spec at:

  http://java.sun.com/docs/books/jls/html/3.doc.html#101083

Hope that answers your questions!

- Paul Philion

Ben Coppin wrote:
>
> 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

___________________________________________________________________________
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

Reply via email to