We were doing some performance comparisons of the a custom DataBinding using JAXB and noticed a very large jump in response times when combining JAXB marshalling and GZIPFeature. Without compression, we saw 24 ms response times, of that 3 ms were spent in our custom DataBinding that uses javax.xml.bind.Marshaller.marshal(Object, XMLStreamWriter). With compression, our sample messages were seeing 400 ms response times, of that most was in the marshal call. I notice CXF is using the same call for its JAXBDataBinding, so wanted to raise what I've found so anyone else interested can validate the same with stock CXF.
After adding some monitoring, I found a big gain by adding a very simple fix: The GZIPOutInterceptor needs a BufferedOutputStream wrapping the GZIPOutputStream. I did this with a custom Interceptor that I installed, after(GZIPOutInterceptor.class.getName()). On just the server Out, this reduced response times from 100 ms, and out serialization to 5 ms. Need to do some more tweaks to add it to client side as well, which should reduce that 100 ms number even further. The reason this makes a difference, at least on Windows, is that JAXB makes hundreds of calls to the OutputStream it is passed, in this case GZIPOutputStream. This means hundreds of JNI calls and a lot of kernel context switching. With the BuffferedOutputStream, those calls are reduced to a couple dozen, on a much larger data set that makes the Deflater much more efficient. Environment: JAXB 2.1 (JDK 6) CXF 2.3.2 Windows Server 2003 4 request threads
