I have a program I ported from C to Java. Both apps use quicksort to order some partitioned data (genomic coordinates).
The Java version runs fast, but I'd like to get it closer to the C version. I am using the Sun JDK v6u14.
Obviously I can't get parity with the C application, but I'd like to learn what I can do to eke out as much performance as reasonably possible (within the limits of the environment).
What sorts of things can I do to test performance of different parts of the application, memory usage, etc.? What would I do, specifically?
Also, what tricks can I implement (in general) to change the properties and organization of my classes and variables, reducing memory usage and improving speed?
EDIT : I am using Eclipse and would obviously prefer free options for any third-party tools. Thanks!
Use a profiler:
Use the latest version of JVM from your provider. Incidentally Sun's Java 6 update 14 does bring performance improvements.
Measure your GC throughput and pick the best garbage collector for your workload.
do not try to outsmart the jvm.
in particular:
don't try to avoid object creation for the sake of performance
use immutable objects where applicable.
use the scope of your objects correctly, so that the GC can do its job.
use primitives where you mean primitives (e.g. non-nullable int compared to nullable Integer)
use the built-in algorithms and data structures
when handing concurrency use java.util.concurrent package.
correctness over performance. first get it right, then measure, then measure with a profiler then optimize.
Can't you use the sort functions that are included in the Java library?
You could at least look at the speed difference between the two sorting functions.
Here's what I would do, in any language. If samples show that your sort-comparison routine is active a large percentage of the time, you might find a way to simplify it. But maybe the time is going elsewhere. Diagnose first, to see what's broken, before you fix anything. Chances are, if you fix the biggest thing, then something else will be the biggest thing, and so on, until you've really gotten a pretty good speedup.
Methodolically, you have to profile the application and then get an idea of what components of your program are time and memory-intensive: then take a closer look to that components, in order to improve their performances (see Amdahl's law).
From a pure technological POV, you can use some java-to-nativecode compilers, like Excelsior's jet, but I've to note that recent JVM are really fast, so the VM should not impact in a significative manner.
Obviously, profile profile profile. For Eclipse there's TPTP. Here's an article on the TPTP plugin for Eclipse. Netbeans has its own profiler. jvisualvm is nice as a standalone tool. (The entire dev.java.net server seems to be down at the moment, but it is very much an active project.)
The first thing to do is use the library sorting routine, Collections.sort; this will require your data objects to be Comparable. This might be fast enough and will definitely provide a good baseline.
General tips:
StringBuilder
(notStringBuffer
because of that lock thing I just mentioned) instead of concatenatingString
objectsfinal
; if possible, make your classes completely immutableArrayList
(or even an array) so the memory you're accessing is contiguous instead of potentially fragmented the way it might be with aLinkedList