Java Optimization

Optimizing

Compared to natively compiled programs in other languages, Java programs generally have reduced performance. However, optimization techniques can be employed to increase your program's performance greatly in some cases.

First of all I would like to point out that you shouldn't optimize your code unless you really need to. A lot of time can be spent optimizing, but with little gain in overall performance. The best thing to do is pinpoint the bottlenecks in your code and concentrate on either optimizing them, or completely redesigning them. If you can make a better algorithm (high-level optimization), this will probably increase the performance much more than low-level optimizations.

The 90/10 rule

Generally speaking 90% of a program's execution time is spent executing 10% of the code. As I said above, a lot of your optimizations on the other 90% of the code will not have much effect on the performance. So first of all you need to pinpoint the bottlenecks in your program (where 90% of the execution is spent). A lot of the time you need to look carefully at fragments of code which are executed frequently (e.g. in a loop). I will try and go through the different optimization techniques which mainly concern restructuring your code.

Code optimization techniques

Certain common optimization techniques such as using CPU registers, global register allocation and so on don't apply to Java bytecode. In a way this is a good way to improve programming technique. Instead of trying squeeze more performance out of programs by hacking in assembly language, I'm sure you could improve the design of your algorithms and yield much greater performance in doing so.

However, code optimization doesn't necessarily mean speed optimization. Sometimes it is necessary to employ other types of optimizations. The three main types are:

Note that optimization should always be performed after you get your code working, not before. Also bear in mind that certain programming "habits" can also be used to optimize your code. If you use these while you're programming, it will result in faster/smaller/more maintainable code with a lot less work. It will save you going back and editing all your coding.

Pinpointing bottlenecks

As I have mentioned, you should never try and optimize all your code. This will allow you to focus your efforts on the code which drains the performance, and not spend hours trying to improve the code.

Isolating speed bottlenecks is not difficult if you uses not difficult if you use appropriate tools. You can use a profiler to find the amount of time spent executing each section of code. To profile a (single-threaded) application using the runtime interpreter profiler, use:

java -prof ClassName

where ClassName is the name of the Java program you want to profile. To profile applets, use:

java -prof sun.applet.AppletViewer file.htm

When you have finished running the program, the interpreter writes all the profiling information to the current directory. This information consists of a list of methods sorted by how many times each method was called during the execution of the program.

Methods at the top of the list are called more than other methods, so you should give most of your attention to these methods. Obviously small optimizations in a method which is called 1000 times will have a much greater impact on overall performance than code which is executed 100 times. Try different optimizations and then run the profiler again to see how much performance has increased.