fun with Java

Brian Burton <[email protected]> Tue, 15 Nov 2005 21:20:10 -0500
Newsgroups gmane.mail.spam.spamprobe.general
Message-ID <[email protected]>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Wow.  I like to think of myself as a guy who isn't prone to naive 
flights of fancy.  I'm a practical man.  Sure, I program in Java for a 
living but I have a good understanding of the trade offs involved.  Java 
has huge advantages in development time and security over C and C++. 
The price you pay for these (big) benefits is increased memory 
consumption and slower execution.  When I wanted performance I'd switch 
to C++ for raw execution speed.  I'd pay the price in increased 
development time, memory management debugging, etc.  I knew all this, 
had experienced it in the past, and didn't think much more of it.

Then last week I read about the release of GCJ 4.x and how much GCJ had 
improved since I last played around with it.  I started to get really 
excited at the prospect of a completely open source Java execution 
environment that would run on just about all open source OS's.  It 
brought back the grand dreams I'd had when I experimented with mono a 
year or so ago.  After all I've been programming in C++ for years and 
like the language but, I have to admit, I enjoy Java development a whole 
lot more.

So I decide to give GCJ a fair test.  Over the last week or so I've been 
porting some of the spamprobe code over to Java.  What I have is 
basically just the parsing code.  The Java implementation uses the same 
well factored (IMHO) design as the C++ spamprobe implementation so there 
wouldn't be any question about differences in algorithms causing 
performance differences.  This would be an excellent barometer for what 
to expect if I moved forward with a full Java implementation.

Writing the Java port was a hoot.  I was able to strip out all of the 
nasty C++ memory management code (yuck) since in Java the GC would take 
care of all of that for me.  I could also write and run unit tests using 
junit to test each class as I went.  I could use the excellent debugging 
and refactoring tools in IDEA to make the coding more fun.  It was a lot 
of fun and I couldn't wait to get to the point where I had a program to run.

Well, finally this evening I was able to do a side by side comparison. 
I wrote a program in Java that parses an mbox file and dumps out some of 
the headers for each message along with the tokens in the message in 
alphabetical order.  There isn't any database access involved.  Just 
straight parse and print.  I then modified the spamprobe.cc file to add 
a new command that does exactly the same thing.

I compiled the Java program using gcj to produce a native executable 
(using -O4).  That gave me three different programs to test:  spamprobe 
(native C++), a gcj compiled native Java program, and a bytecode Java 
program running inside of Sun's JDK (using hotspot).

I downloaded a big mbox file containing a lot of spams to my laptop 
(yuck, will have to scrub the drive to remove the slime later) proceeded 
to run all three programs parsing the file multiple times per run and 
dumping to /dev/null.

Here is the summary (average over several runs):

   Program              Seconds        Res. MB
   spamprobe               49          1.8-2.4
   native gcj program     124             17.0
   hotspot program        202           40-400

I had a lot of trouble running under hotspot.  That's really weird.  I 
got OutOfMemory errors from the VM until I ran it with -Xmx512m (max 
heap size 512 MB!).  That's got to be a bug in the VM.  I'll have to 
investigate it more.

So the native C++ program came in at approx. 2.5x faster and used 
approx. 1/10 the resident memory size of the native java program.  Wow. 
  I was really hoping that a natively compiled Java program would be 
around 80-90% the performance of a C++ program.  Not even close.

The memory usage difference floored me.  I spent a LOT of time on the 
memory management code in spamprobe so I knew it was pretty tight. 
Still, I didn't expect the Boehm GC to let the heap grow quite as big as 
it did.

I'll continue to play with this (it's fun) and see if there are knobs I 
can turn or buttons I can push to change gcj's optimizations to get 
better performance.

I just wanted to share this with the list in case anyone found it 
interesting.

All the best,
++Brian

-----BEGIN PGP SIGNATURE-----
Version: PGP Desktop 9.0.2 (Build 2425)

iQEVAwUBQ3qXaDxRyEoJfXIFAQgguAf6Agz7rxZmj6Qeo75eJHB9DoHSSPIwpagT
bHkSgCE575iIopfNmHC5SmRNs0IQT1HtKMhvHYhEShuFfz5WY9BE84cJTE3bdsOZ
GLocm18qyHRf9ISoSyX2gol9qmjwD5iRt2eNpg3426vbaD2+2oN0Nm5Viu6zOBPb
5NdNO7NcubLHAbSpfSzagvlw2b5QltgQ2lPHkk1SvghdzMBBbCh/paO4CF6hmLkN
OZjYmC/bqX1JWCDvPiuPHfwLa2fcOMskovQbFeEZLyYD3jllSgT7og4LSWCBXAsg
uOwP9HQgPxGL0AOxJUXgHN8zI8X07spJr+B72MmLdheMRrKoVvvb3Q==
=9FRH
-----END PGP SIGNATURE-----


-------------------------------------------------------
This SF.Net email is sponsored by the JBoss Inc.  Get Certified Today
Register for a JBoss Training Course.  Free Certification Exam
for All Training Attendees Through End of 2005. For more info visit:
http://ads.osdn.com/?ad_id=7628&alloc_id=16845&op=click