Hi All,

On CXF 2.0.7, I was evaluating the performance of MTOM for sending attachments for both enabled and disabled scenarios. As promised by MTOM, I am able to see around 30% message-size optimization compared to Base64 encoded messages. But surprisingly, the time taken by the MTOM enabled scenarios are more than expected..

My simple test includeed, sending a string and a raw byte array in a request and receiving them back as a response.

   public void testMtom(
@WebParam(mode = WebParam.Mode.INOUT, name = "name", targetNamespace = "http://cxf.apache.org/mime/types";)
       javax.xml.ws.Holder<java.lang.String> name,
@WebParam(mode = WebParam.Mode.INOUT, name = "attachinfo", targetNamespace = "http://cxf.apache.org/mime/types";)
       javax.xml.ws.Holder<javax.activation.DataHandler> attachinfo
   );

I performed above test, for varying sizes of  byte array from 32KB to 12MB.

I checked where it is taking unreasonably more time during request and response cycle. I found following as my observations:

1. StaxUtils Change: XML Namespace aware and unaware factories are created as static members of StaxUtils. Moving them to an static method which initializes them as needed. This gives an improvement of around 50 ms on both client and server StaxInterceptors performance, like,

public static XMLInputFactory getXMLInputFactory(boolean nsAware) {
      if (nsAware) {
          if (XML_NS_AWARE_INPUT_FACTORY == null) {
              XML_NS_AWARE_INPUT_FACTORY = XMLInputFactory.newInstance();
XML_NS_AWARE_INPUT_FACTORY.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, true);
          }
          return XML_NS_AWARE_INPUT_FACTORY;
      }else {
          if (XML_INPUT_FACTORY == null) {
              XML_INPUT_FACTORY = XMLInputFactory.newInstance();
XML_INPUT_FACTORY.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, false);
          }
          return XML_INPUT_FACTORY;
      }
}

2. MimeBodyPartInputStream Change: read(bytes[], int off, int len) method is implemented. Parent class InputStream serves the method invocation. This is reads a byte and processes them in the MimeBodyPartInputStream. An alternative implementation having read(buf, off, len) in MimeBodyPartInputStream works 6 times faster than this one. To check the performance of this alternative MimeBodyPartInputStream implementation, I wrote a simple test program which just reads an inputstream and processes the same boundary check for both alternative and CXF MimeBodyPartInputStream implementation. For 12 MB data, this takes around 250 ms, whereas CXF original takes for around 1250 ms. If require I can give a patch of this alternate MimeBodyPartInputSteam file.

3. AttachmentInInterceptor Change: AttachmentDeserializer contains static java.util.regex.Patterns which required to be compiled for particular String expressions, which takes substantial time in milliseconds. AttachmentDeserializer instance is created in AttachmentInInterceptor during handleMessage() call. This can be moved to AttachmentInInterceptor constructor, and provided a setMessage(Message message) method in AttachmentDerserializer, we can set message during handleMessage() call.

4. AttachmentUtil Change: I am not sure about whether we require a Universally Unique ID as a Mime Content ID or not? It may the case that for adherence to the specification or Interoperability with other vendors we may require UUID. A Universally Unique ID is being created for each attachment for the message. If in case MIME Spec doesn't restrict to have an universally unique id, a sequential counter can be used to provide unique identifiers for different attachments in a message. This also saves a substaintial time.

MTOM enable scenario perform better using these changes.

With Regards,
Mayank

Reply via email to