Sorry for the cross posting, but I thought that you people would appreciate
this as well...;-)

-jon


----------
From: Stefano Mazzocchi <[EMAIL PROTECTED]>
To: _ Java Apache <[EMAIL PROTECTED]>
Subject: Still making 1.0b4-dev faster...
Date: Fri, Apr 9, 1999, 7:48 AM


Hi,

I went on profiling the JServConnection class and I totally rewrote the
readHexData() and readData() methods that were shown to be major
hotspots in the code. My final results are incredible!

What was wrong
--------------

The AJP1.1 protocol was designed with simplicity in mind and for that
reason it was based on text protocols like HTTP. For this reason, the
server side must perform some parsing on the incoming stream to be able
to create the needed strings out of such AJP requests.

The problem was the abuse of String and StringBuffer objects, as well as
a very poor knowledge of how GC works. This is reflected from the old
days of 9.0 and it's been around since there (Ed indipendently came out
with the same ideas for 0.9.12. Too bad I noted we were doing the same
things after I was done changing it :-(.

What I did
----------

1) optimized the HEX to decimal translation with a lookup table insted
of java.lang.Character methods. I tried to avoid to touch internal byte
to char translations and such because of the Unicode overhead we do not
care since mod_jserv doesn't even know about it.

2) used an adaptive byte[] buffer (just one per JServConnection!)
instead of creating a new String for every line. This alone saves almost
_half_ of the memory created by JServConnection.

3) implemented a clean-room C-like implementation of StringBuffer
specifically tuned for our AJP needs. Another big memory save since no
object must be created

4) removed all of the if (xxx == null) methods and change them to
Exception catching (which is both more elegant and faster)

5) inlined the call to readHexLine() to avoid passing parameters around
(as you see from the code, it doesn't hurt readability that much since
it integrates very well with the parsing loop.

Results
-------

I profiled JServ by running it with the two different JServConnection
versions and hitting it with JMeter at 5 threads, 300 ms delay for a
total of around 50 hits (57 for new, 54 for old). JServ was run by the
IBM JInsight instrumented JVM.

The first thing that stroke me was the side of the trace file:

new code trace file size = 5280kb (92,6 kb/request)
old code trace file size = 8400kb (155 kb/request)

the new code generated 40% less traces!

The total number of clock ticks counted for the execution of all the
JServConnection objects indicates the time spent on the execution of the
servlet (both logging and class autoreloading was disabled, compiled
with TURBO mode on)

new JServConnection total time = 8187707 ticks (143644 ticks/request)
old JServConnection total time = 11556202 ticks (214004 ticks/request)

the new code is 33% faster!!!!

If you used to load balance with three machines, you can now use two and
dedicate the third to your coffee pot ;-)

If we take into account the memory savings (that reflects on GC being
called less frequently) we see how much we gain from this little hack
;-)

BTW, keep in mind that YMMV! (numbers in real life welcome!)

Stefano Mazzocchi       A language that doesn't affect the way you
                      think about programming, is not worth knowing.
<[EMAIL PROTECTED]>                             Alan J. Perlis
---------------------------------------------------------------------



------------------------------------------------------------
To subscribe:        [EMAIL PROTECTED]
To unsubscribe:      [EMAIL PROTECTED]
Archives and Other:  <http://java.apache.org/main/mail.html/>
Problems?:           [EMAIL PROTECTED]



----------------------------------------------------------------
To subscribe:        [EMAIL PROTECTED]
To unsubscribe:      [EMAIL PROTECTED]
Archives and Other:  <http://java.apache.org/main/mail.html/>
Problems?:           [EMAIL PROTECTED]

Reply via email to