>>> Tom Copeland <[EMAIL PROTECTED]> 15-Jun-00 7:13:06 PM >>>

Warning: long and complex explanation coming up

> out.write(html.getBytes());
>  makes this code MUCH faster.   Specifically, I observed
>the following performance for sample large & small pages:
> I don't know... maybe everyone is doing this already... but I
>wasn't, and now my servlets are noticeably faster - and, as far
>as I can tell, the performance gain is "free".  So, is there
>something I'm missing here?
>Does using out.write(html.getBytes()); do something bad?
>If not... why do many servlet books and tutorials use the
>OutputStream println() method?

the performance of the output stream depends upon the Servlet
container's output stream implementation.

The class javax.servlet.ServletOutputStream is implemented rather
poorly from what I remember... it does things like this:

  public void println(String s)
  {
     for(int i=0; i<s.length(); i++)
     {
       write(s.charAt(i));
     }
  }

This generates one method call per character in the string. Method
calls are expensive, they are also difficult to optimize away, so this
is not a good implementation... what it should do is something like
this:

  public void println(String s)
  {
     byte[] arr=s.getBytes();
     write(arr,0,arr.length);
  }

This goes straight to the heart of the matter and the stacked calls
may be easier for the compiler and the VM to optimize.

Unfortunately this has problems too... namely that the character
encoding of the string is lost and you have to rely on the default
encoding.

So ServletOutputStream is stuck doing what it does. It's a bad design
basically.

This is not the end of the story however.

Servlet Containers need to override ServletOutputStream in order to
connect it to the OutputStream connected to the TCP Socket.

If a servlet container does not override the entire class to
re-implement the methods in a more intelligent way then the user is
stuck with the poorly performing methods of ServletOutputStream.

This is why you are seeing the performance difference you are
seeing.


What you are doing does have the danger that you will loose character
encoding, if this is of concern you should use the alternative method
which allows you to specify the encoding.

There is another thing you can do to speed it up: you can overload
the ServletOutputStream yourself. I wrote a class
LowImpedanceOutputStream that is implemented to use the lowest
resistance output method possible and takes an existing OutputStream
as an argument, eg:

  public void doGet(...
  {
     ServletOutputStream sout=response.getOutputStream();
     LowImpedanceOutputStream out=
        new LowImpedanceOutputStream(sout);
     out.println("hello there");  //will be done via the
write(byte[],int,int) method
     .
     .
     .
    out.close();
  }

My webserver/container (GNU-Paperclips) uses this automagically and
thus has no problems with this speed difference.


Nic Ferrier

___________________________________________________________________________
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