Getting Performance with Java
(a.k.a Nalini's words of wisdom)
Nalini Belaramani
Feburary 2008
As systems researchers, performance numbers are integral part of
papers we publish. Working with Java makes it a bit difficult to get
excellent performance numbers, but nonetheless, it can be done. (Thought
to self: Am I trying to fool myself?)
Here are just a few pointers which I hope are helpful in your quest to
get good performance data. Some of you may already know this and it
may not be a surprise. If there is any other suggestions you have,
please do let me know.
Tip 1: Experiment with different JVM's (JRockit suggested!)
Different JVM's have different optimization techniques, GC algorithms,
memory management algorithms.
I tried Bea JRockit (R27.4.0) and I got better performance than Sun JVM
(1.5.0_07).
The advantage of JRockit is that it has lots of options to tweak
optimizations, GC algorithms, logging options and you can use those to
debug your performance, isolate memory leaks. All that comes free!
reference: http://www.bea.com
Tip 2: Ignore the 1st iteration when measuring results
I found that if you want to get the average time it takes for doing a
write, instead averaging the time it takes to do each of the 1000
writes, do 1001 writes and ignore the 1st iteration.
The reason is that during the 1st iteration, the JVM actually
compiles your code (thanks to JIT), and so the 1st iteration
measurement includes the compilation time as well.
Tip 3: Play with the Heap
Experiment with different heap sizes. Also, try initializing the
whole heap from the beginning. i.e. java -Xms256M -Xmx256M
This has 2 advantages:
- the JVM does not need to spend time expanding the heap when it runs
out of heap spac
- depending on the implementation, if the GC is invoked when a certain
percent of the heap is full, with the heap already allocated to max
capacity, the GC will be invoked much later. However, it may take
more time to GC because of the larger heap
Hopefully, you will see less peaks in your measurements.
Tip 4: Forget about the Peaks
Since JVMs do a lot of things under the hood, to get a true reflection
of your performance, ignore the peaks in your measurements.
There could be a variety of reasons for the peaks: the complier (JIT
decides to optimize your code further), memory compaction, GC, etc.
By ignoring, say, 10 percent of the worst iterations, you may be able
to get a better idea of your system's performance.
(This is good for debugging performance. If you do ignore the
peaks in the results of your paper, remember to mention it.)
Tip 5: Changes to Code
There an extensive list of websites with programming techniques for
getting all the performance you need from Java. You may want to check
them out (google them!).
Here are a few simple ones which may help.
- Constructors and static methods are often not compiled so put your
logic in non-static methods.
- Don't initialize objects which require large contiguous memory
for e.g. a 1MB byte array, because they are difficult to allocate on the
heap (i.e heap may need to be compacted to fit them, GC may need to
be called to make space, etc.)
- In a loop, try not to declare new variables each time, but re-use
previously declared variables. This supposedly helps GC identify
unreferenced objects.
Instead of :
for(int i = 0; i < n; i++) {
long start = System.currentTimeMillis();
MyObject obj = new MyObject(i);
...
long end = System.currentTimeMillis();
...
}
Declare variables outside the loop:
long start, end;
MyObject obj;
for(int i = 0; i < n; i++) {
start = System.currentTimeMillis();
obj = new MyObject(i);
...
end = System.currentTimeMillis();
...
}
Tip 6: Play with Berkeley DB Cache Size
Berkeley DB also does a lot of stuff under the hood. It has threads
which flush the cache to the disk, clean up old log files, take
checkpoints etc.
I found that a large cache size reduced the peaks in my measurement.
I traced it to the fact the cleaner thread was invoked less
frequently. On the other hand, some websites claim that too large a
cache size may also adversely affect performance.
In short, you may need to find the cache size which works best for
your system and workload.
Conclusion:
Take these tips with a grain of salt. Some of them may work for you,
some of them may not. The important thing is to have fun while you are at it.