The Source for Java Technology Collaboration
User: Password:



Jayson Falkner's Blog

Extreme Programming Archives


Blarg #7: How long does it takes to compress a response using a GZIP filter?

Posted by jfalkner on January 27, 2004 at 09:13 PM | Permalink | Comments (1)

Hi, just found out about your book the other day from java.net and was really grateful for the example of the Compression code. I've had to implement that in the past on the web server level and it was a real pain then, but this was relatively effortless. I'm adding this book to my to-buy list.

I do have a question. Perhaps if others are interested some sort of improvement could be integrated. Where would we add output messages that would help us with the timing of the compression?

i.e.If I put something like this in GZipFilter:

                 System.out.println("GZIP supported, compressing.");
                 long ini = System.currentTimeMillis();
                 GZIPResponseWrapper wrappedResponse = new
 GZIPResponseWrapper(response);
                 chain.doFilter(req, wrappedResponse);
                 wrappedResponse.finishResponse();
                 System.out.println("Compressed in " +
 (System.currentTimeMillis()-ini) + " ms");

I get the total time for the entire request, not just the time it takes to do the compression. >From testing I realize the compression time is pretty short, say in the order of tens of microseconds, but I'm still pretty interested. I was thinking that moving the time initializer from before the response constructor to before the finishResponse method call would work, but I wasn't sure if that would get the total compression time, or just the time for the last output to be flushed from the response buffer.

Thanks,
Ronald

Hi Ronald,

Awesome. I'm glad you found my book, and I hope you enjoy it.

The trick here is to split the request and compression in to two separate things. Buffer the response, then compress the buffer and time only the compression. You can more or less do this easily by editing the code in the com.jspbook.GZIPResponseStream class, e.g. here is the existing code in the close() method of GZIPResponseStream.

ByteArrayOutputStream baos = (ByteArrayOutputStream)bufferedOutput;
// prepare a gzip stream
ByteArrayOutputStream compressedContent = new ByteArrayOutputStream();
GZIPOutputStream gzipstream = new GZIPOutputStream(compressedContent);
byte[] bytes = baos.toByteArray();
gzipstream.write(bytes);
gzipstream.finish();
// get the compressed content
byte[] compressedBytes = compressedContent.toByteArray();

You can see the response gets put in to a byte array, then the byte array is compressed and the results are saved to another byte array. You could put a time check in as follows (very similar to what you were doing).

ByteArrayOutputStream baos = (ByteArrayOutputStream)bufferedOutput;
// prepare a gzip stream
ByteArrayOutputStream compressedContent = new ByteArrayOutputStream();
long ini = System.currentTimeMillis(); // <------- starting timing here
GZIPOutputStream gzipstream = new GZIPOutputStream(compressedContent);
byte[] bytes = baos.toByteArray();
gzipstream.write(bytes);
gzipstream.finish();
// get the compressed content
byte[] compressedBytes = compressedContent.toByteArray();
System.out.println("Compressed in " + (System.currentTimeMillis()-ini) +
" ms"); // <-------------- stop timing here

And the result is you are only counting how long the compression took. Although fair warning needs to be given. The current GZIPResponseStream class tries to buffer content, as shown above (it allows you to set the content-length header properly), but when compressing really big files the filter streams content back to the client as not to use up all of your web application's memory. The above timing example won't work if you are testing it on files larger than the buffer -- the default buffer is 50k, you may need to increase it for your benchmark.

In general, the resources it takes to compress content aren't an issue. However, if you find that compression takes up too much processing power, remember you can combine compression with caching to try and reduce the overhead.

Cheers, Jayson Falkner jayson@jspinsider.com

A few links





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds