Scott, Here is server time picture taken on the Tomcat server , processing ComplexRequest. The red ellipses show that MimePart initialization takes 10-15% of CPU load. The blue ellipses show that ContentType is also quite expensive for benefits it provide. I prepared patch for caching ContentType...
Pavel > -----Original Message----- > From: Scott Nichol [mailto:snicholnews@;scottnichol.com] > Sent: Wednesday, November 13, 2002 5:48 PM > To: [EMAIL PROTECTED] > Subject: Re: Using mime parts - huge drawbacks > > > Pavel, > > Yes, this is a good observation. In the case where there are no > attachments, the process could be streamlined by serializing directly. > I am still actively working on this part of the code > (TransportMessage, > SOAPContext, Call) and will look at sidestepping some of the activity > where there are no attachments, just a SOAP envelope, which > as you point > out is the typical scenario. > > Scott Nichol > > ----- Original Message ----- > From: "Pavel Ausianik" <[EMAIL PROTECTED]> > To: <[EMAIL PROTECTED]> > Sent: Wednesday, November 13, 2002 9:04 AM > Subject: Using mime parts - huge drawbacks > > > > Hello, > > > > thinking more on the current code I have found interesting > thing. Most > > requests we have a simple, straight SOAP envelopes, without any > attachments. > > Looking how it is processed I have found following (traced from > > httpconnection): > > > > In SOAPHTTPConnection.send() we call TransportMessage.save(). > > Let's look into it (see my comment how I understand it: > > > > String rootContentType = null; > > > > // Root Part is Not set for Simple Envelope ! > > > > if (ctx.isRootPartSet()) { > > //... Not in use for simple case > > } > > > > if (rootContentType == null) > > rootContentType = Constants.HEADERVAL_CONTENT_TYPE_UTF8; > > if (getEnvelope() != null) { > > > > // Now really create root part - how important it is if we > now how to > write > > this Envelope without involving Mime !!! > > > > ctx.setRootPart(envelope, rootContentType); > > } else { > > //... Not in use for simple case > > } > > > > // Print the whole response to a byte array. > > // Tracing into this code we'll found that all it will do it add > > unnecessary header to envelope > > // The headers include Content-Type - we know which is, > > // Content-id - do we need it? Even if yes we can create any id > > // Content-Transfer-Encoding - not for HTTp, anyway we force it to 8 > bit > > // Content-Lenght - easy to calculate > > > > ByteArrayOutputStream payload = > > new ByteArrayOutputStream(1024); > > ctx.writeTo(payload); > > bytes = payload.toByteArray(); > > > > // Now strip off the headers. (Grmbl, get rid of JavaMail > > // for MIME support). Just intercept the Content-Type > > // Remove headers which created right now.... > > > > .... > > > > // TODO: should not send for HTTP response > > headers.put("Accept-Encoding", "x-gzip"); > > if (Boolean.TRUE.equals(ctx.getGzip())) { > > // Deflate > > ByteArrayOutputStream baos = > > new > ByteArrayOutputStream(bytes.length > * 2); > > GZIPOutputStream gzos = new GZIPOutputStream(baos); > > gzos.write(bytes, offset, bytes.length - offset); > > gzos.close(); > > baos.close(); > > bytes = baos.toByteArray(); > > offset = 0; > > > > headers.put("Content-Encoding", "x-gzip"); > > } > > > > Seems like we are doing wonderful job of running a lot unnecessary > > operations, involving a lot of memory allocations... It > could be most > > advanced improvement we ever done! > > > > Best regards, > > Pavel > > > > > > > > -- > > To unsubscribe, e-mail: <mailto:soap-dev-unsubscribe@;xml.apache.org> > For additional commands, e-mail: <mailto:soap-dev-help@;xml.apache.org> > > -- To unsubscribe, e-mail: <mailto:soap-dev-unsubscribe@;xml.apache.org> For additional commands, e-mail: <mailto:soap-dev-help@;xml.apache.org>
<<attachment: untitled.GIF>>
Index: TransportMessage.java =================================================================== RCS file: /home/cvspublic/xml-soap/java/src/org/apache/soap/transport/TransportMessage.java,v retrieving revision 1.19 diff -u -r1.19 TransportMessage.java --- TransportMessage.java 14 Nov 2002 05:00:42 -0000 1.19 +++ TransportMessage.java 14 Nov 2002 13:46:08 -0000 @@ -169,7 +169,7 @@ if (contentLength != 0) { int offset = 0; int bytesRead = 0; - + // We're done reading when we get all the content OR when the stream // returns a -1. while ((contentLength < 0 || offset < contentLength) && (bytesRead >= 0)) { @@ -258,15 +258,12 @@ // Parse and validate content type. ContentType cType = null; if (contentType != null) { - try { - // Hack since WebSphere puts ;; instead of just ; - int pos = contentType.indexOf( ";;" ); - if ( pos != -1 ) - contentType = contentType.substring(0,pos) + - contentType.substring(pos+1) ; - cType = new ContentType(contentType); - } catch(ParseException pe) { - } + // Hack since WebSphere puts ;; instead of just ; + int pos = contentType.indexOf( ";;" ); + if ( pos != -1 ) + contentType = contentType.substring(0,pos) + + contentType.substring(pos+1) ; + cType = MimeUtils.getContentType(contentType); } if (cType == null) throw new SOAPException(Constants.FAULT_CODE_PROTOCOL, @@ -321,7 +318,7 @@ // Find root part. rootPart = ctx.getRootPart(); - rootContentType = new ContentType(rootPart.getContentType()); + rootContentType = MimeUtils.getContentType(rootPart.getContentType()); ByteArrayDataSource bads = new ByteArrayDataSource( rootPart.getInputStream(), null); rootBytes = bads.toByteArray(); @@ -420,7 +417,7 @@ new ByteArrayOutputStream(65536); ctx.writeTo(payload); bytes = payload.toByteArray(); - + // Now strip off the headers. (Grmbl, get rid of JavaMail // for MIME support). Just intercept the Content-Type // header. We don't want any of the MIME headers, and we know the @@ -514,7 +511,7 @@ MimeBodyPart rootPart = ctx.getRootPart(); if (rootPart != null) { String ctype = rootPart.getContentType(); - ContentType type = new ContentType(ctype); + ContentType type = MimeUtils.getContentType(ctype); if (type != null && Constants.CTYPE_TEXT_ALL.match(type)) { ByteArrayDataSource ds = new ByteArrayDataSource( rootPart.getInputStream(), ctype); Index: Constants.java =================================================================== RCS file: /home/cvspublic/xml-soap/java/src/org/apache/soap/Constants.java,v retrieving revision 1.28 diff -u -r1.28 Constants.java --- Constants.java 14 Nov 2002 05:00:42 -0000 1.28 +++ Constants.java 14 Nov 2002 13:47:35 -0000 @@ -59,6 +59,7 @@ import org.apache.soap.util.xml.QName; import javax.mail.internet.ContentType; +import org.apache.soap.util.mime.MimeUtils; /** * <em>SOAP</em> constants. @@ -85,7 +86,7 @@ "http://schemas.xmlsoap.org/soap/envelope/"; public static final String NS_URI_SOAP_ENC = "http://schemas.xmlsoap.org/soap/encoding/"; - + public static final String NS_URI_1999_SCHEMA_XSI = "http://www.w3.org/1999/XMLSchema-instance"; public static final String NS_URI_1999_SCHEMA_XSD = @@ -143,7 +144,7 @@ public static final String HEADERVAL_CONTENT_ENCODING = "gzip"; // XML Declaration string - public static final String XML_DECL = + public static final String XML_DECL = "<?xml version='1.0' encoding='UTF-8'?>\r\n"; // Element names. @@ -308,9 +309,9 @@ public static final QName object2001QName = new QName(Constants.NS_URI_2001_SCHEMA_XSD, "anyType"); - public static final ContentType CTYPE_TEXT_ALL = new ContentType("text", "*", null); - public static final ContentType CTYPE_TEXT_XML = new ContentType("text", "xml", null); - public static final ContentType CTYPE_MULTIPART = - new ContentType(HEADERVAL_CONTENT_TYPE_MULTIPART_PRIMARY, "*", null); + public static final ContentType CTYPE_TEXT_ALL = MimeUtils.getContentType("text/*"); + public static final ContentType CTYPE_TEXT_XML = +MimeUtils.getContentType("text/xml"); + public static final ContentType CTYPE_MULTIPART = MimeUtils.getContentType( + HEADERVAL_CONTENT_TYPE_MULTIPART_PRIMARY + "/*"); } Index: SOAPContext.java =================================================================== RCS file: /home/cvspublic/xml-soap/java/src/org/apache/soap/rpc/SOAPContext.java,v retrieving revision 1.13 diff -u -r1.13 SOAPContext.java --- SOAPContext.java 6 Nov 2002 18:08:04 -0000 1.13 +++ SOAPContext.java 14 Nov 2002 13:51:01 -0000 @@ -476,7 +476,7 @@ public MimeBodyPart getRootPart() throws MessagingException { MimeBodyPart rootPart = null; if (getCount() > 1) { - String startCid = new ContentType( + String startCid = MimeUtils.getContentType( parts.getContentType()).getParameter("start"); if (startCid != null) rootPart = getBodyPart(MimeUtils.decode(startCid)); Index: MimeUtils.java =================================================================== RCS file: /home/cvspublic/xml-soap/java/src/org/apache/soap/util/mime/MimeUtils.java,v retrieving revision 1.5 diff -u -r1.5 MimeUtils.java --- MimeUtils.java 6 Sep 2002 17:50:27 -0000 1.5 +++ MimeUtils.java 14 Nov 2002 13:53:19 -0000 @@ -70,6 +70,8 @@ */ public class MimeUtils { + + private static HashMap contentTypes = new HashMap(); /** * Get a unique value. * @@ -100,11 +102,8 @@ */ public static String getEncoding(String type, String defaultEncoding) { String encoding = null; - try { if (type != null && !type.equals("")) - encoding = new ContentType(type).getParameter("charset"); - } catch(ParseException pe) { - } + encoding = getContentType(type).getParameter("charset"); if (encoding == null) encoding = defaultEncoding; else @@ -135,5 +134,24 @@ } } return ret.toString(); + } + + /** + * Return a content type from shared pool + */ + public static ContentType getContentType(String ctype) { + synchronized (contentTypes) { + ContentType type = (ContentType)contentTypes.get(ctype); + if (type == null) { + try { + type = new ContentType(ctype); + } + catch (ParseException e) { + return null; + } + contentTypes.put(ctype, type); + } + return type; + } } } Index: Call.java =================================================================== RCS file: /home/cvspublic/xml-soap/java/src/org/apache/soap/rpc/Call.java,v retrieving revision 1.20 diff -u -r1.20 Call.java --- Call.java 12 Nov 2002 14:34:56 -0000 1.20 +++ Call.java 14 Nov 2002 13:58:00 -0000 @@ -66,6 +66,7 @@ import org.xml.sax.*; import org.apache.soap.util.xml.*; import org.apache.soap.util.IOUtils; +import org.apache.soap.util.mime.MimeUtils; import org.apache.soap.*; import org.apache.soap.encoding.*; import org.apache.soap.transport.*; @@ -273,10 +274,7 @@ MimeBodyPart rootPart = respCtx.getRootPart(); String ctype = rootPart.getContentType(); ContentType type = null; - try { - type = new ContentType(ctype); - } - catch (ParseException e) {} + type = MimeUtils.getContentType(ctype); if (type != null && Constants.CTYPE_TEXT_ALL.match(type)) { // Get the input stream to read the response envelope from.
-- To unsubscribe, e-mail: <mailto:soap-dev-unsubscribe@;xml.apache.org> For additional commands, e-mail: <mailto:soap-dev-help@;xml.apache.org>