axis-java-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Fernandez Martinez, Alejandro" <a.fernandez.marti...@ibermatica.com>
Subject RE: Axis performance reading socket input stream
Date Wed, 29 Oct 2003 18:35:09 GMT
Unluckily, I had done some refactoring of SOAPPart along with the change in
socket reading. As it happens, when I tried to submit a patch with only that
change, that wasn't it -- it was as slow as before, around 3 requests /
second.
 
In fact, it seems that the refactoring was responsible for the performance
gains. I will explain it in brief:
    - The problem seems really to be that, in org.apache.axis.SOAPPart, the
contents is being transformed from bytes to string to envelope (and back)
several times. [The procedure of storing an Object contents, along with an
int that specifies the real type, is not very Java-like, by the way.]
    - SOAPPart is divided into IncomingSOAPPart, OutgoingSOAPPart and
FaultSOAPPart.
    - IncomingSOAPPart is constructed with a byte array, or an input stream.
The input stream is read completely into a byte array. When it is requested
a SOAPEnvelope, it parses the byte array; this is cached locally.
    - OutgoingSOAPPart is constructed with a SOAPEnvelope. When requested a
string or byte array, it serializes the envelope; this is cached locally.
    - FaultSOAPPart works similarly.
    - Finally, org.apache.axis.Message selects the appropriate subclass of
the abstract org.apache.axis.SOAPPart in each constructor.
 
Unfortunately, I don't have the resources here at work to prepare a patch
that touches dozens of files. My modified version has good enough
performance for our needs. But I will make the modifications available for
anyone who is interested in doing the work.
 
Un saludo,
 
Alex.

-----Mensaje original-----
De: Eric.D.Friedman@wellsfargo.com [mailto:Eric.D.Friedman@wellsfargo.com]
Enviado el: miércoles 29 de octubre de 2003 19:26
Para: axis-dev@ws.apache.org
Asunto: RE: Axis performance reading socket input stream



Sounds interesting - you are correct, of course, that you would need to do
multiple reads - you can't simply count on a single read being sufficient,
so a loop until available says "no more" is needed.

 

Also, I would suggest that you set a cap on the size of the arrays you will
create.  That is, you might say that rather than simply allocating byte
arrays as big as InputStream.available replies, you'd take the minimum of
that value and a ceiling (say 4096).

 

So:

 

int available = Math.min(4096, is.available());

 

byte[] buf = new byte[available];

 

This is unlikely to be an issue, but it's good defensive programming.

 

-----Original Message-----
From: Fernandez Martinez, Alejandro
[mailto:a.fernandez.martinez@ibermatica.com] 
Sent: Wednesday, October 29, 2003 1:39 AM
To: axis-dev@ws.apache.org
Subject: Axis performance reading socket input stream

 

Hi folks, 

I have been making some performance tests for Axis, using a local and a
remote machine as SOAP server: just sending a small SOAP message a number of
times. I can give you the specifics if you want; for the moment, suffice to
say that Axis was making about 3 requests/second over a local 100 MBit
ethernet. Quite insufficient for any real-world application.

For comparison, I have also load-tested GLUE from The Mind Electric. I was
getting between 100 and 500 req/s with the same setup.

After looking for the bottleneck, the class org.apache.axis.SOAPPart seems
to be the culprit. Specificially, this snippet from SOAPPart.getAsBytes():

            // Assumes we don't need a content length 
            try { 
                InputStream  inp = null; 
                byte[]  buf = null; 
                try{ 
                    inp = (InputStream) currentMessage ; 
                    ByteArrayOutputStream  baos = new
ByteArrayOutputStream(); 
                    buf = new byte[4096]; 
                    int len ; 
                    while ( (len = inp.read(buf,0,4096)) != -1 ) 
                        baos.write( buf, 0, len ); 
                    buf = baos.toByteArray(); 
                }finally{    
                  if(inp != null && 
                    currentMessage instanceof
org.apache.axis.transport.http.SocketInputStream )    
                    inp.close(); 
                }  
                setCurrentForm( buf, FORM_BYTES ); 
                log.debug("Exit: SOAPPart::getAsBytes"); 
                return (byte[])currentMessage; 
            } 
            catch( Exception e ) { 
                log.error(Messages.getMessage("exception00"), e); 
            } 

It seems that this was stalling for a long time (from zero to 300 ms). A
quick hack resulted in much better performance: now I'm getting from 10 to
100 requests/second.

            try 
            { 
                int available = inputStream.available(); 
                // only read available bytes 
                buf = new byte[available]; 
                inputStream.read(buf); 
            } 
            catch (IOException e) 
            { 
                log.error(Messages.getMessage("exception00"), e); 
            } 

It might have some problems though: 
        - It works OK for HTTP transport, but it might not be flexible
enough for other protocols, 
        - and for big messages it might not work at all. 
It would probably better to read until available is 0 or -1, so that there
is no network stalling. 

I wonder if this issue has come up before, and if you would be interested in
a patch for this. 

Un saludo, 

Alex Fernández. 


Mime
View raw message