Welcome. I want to share with you my experience in optimization of java programs.

First of all note that all tests were run on Pentium 225/64M machine with Windows NT 4.0 SP3 OS so the timing results could slightly be different. Also,I think, it shouldn't matter for you that OS is Microsoft one. This description is far away of those issues.

Let's to try to optimize something. But before the beginning you could say there are several commercial profilers that should measure with microsecond precision. But wait sometime, keep your mind in touch for now. Consider our timer will be the following java class

 Timer.java
public class Timer {
	static long startTime;

	static final void start() {
		startTime=System.currentTimeMillis();
	}
	static final void end() {
		startTime-=System.currentTimeMillis();
	}
	static final void report() {
		System.err.println("Done for "+(-1*startTime)+" ms");
	}
}
It is plain enough, when you want to measure some actions you should call from your code its start() method, end() when the measurement is done and report to print results. Note because in Java we have only 1 ms precision, but that isn't an issue let's repeat actions we want to measure several times. Lets start from usual HelloWorld example.
 HelloWorld.java

public class HelloWorld {
	public static void main(String[] argv) {
		int i,max=100000;
		System.out.println("Testing output: printing "+max+" times");
		Timer.start();

		for(i=0;i
Try to compile it and run.
Be aware of many greating from the console screens. To be not tired of them use something like:
java HelloWorld >nul
By this reason the timing results of Timer class are printed to stderr. I've got following execution timing results:
6200
with Symantec JIT for 1.1.6 and
19000
without it. Then let's modify it. See code for details
 HelloWorld2.java
public class HelloWorld2 {
	public static void main(String[] argv) {
		int i,max=100000;
		System.out.println("Testing output: printing "+max+" times");
		Timer.start();
		String s="Hello World";

		for(i=0;i

The timing results is less about 50 ms with previous in any case. The difference is in following:
Each time java compiler encounters string literal ( something in quotes ) it generates call to constructor of class String. So difference in this case is cost of calling of constructor and probably garbage collection. Indeed, we have created 100000 of new objects. And each time of garbage collection occurs then all java program threads will be suspended. Let's how much is the last part. Consider following example:

 HelloWorld3.java

public class HelloWorld3 {
	public static void main(String[] argv) {
		int i,max=100000;
		System.out.println("Testing output: printing "+max+" times");
		Timer.start();
		byte[] content="Hello World\n".getBytes();

		for(i=0;i
Note that actually this class makes the same thing then couple previous.
After running I've got the following timing results: 
with JIT :
1200
and without:
1900

Wonderful results for beginning: 5 times acceleration for JIT and 10 times for bare running. Note then we can count or approximate the volume of garbage collection by specifing '-verbosegc' flag for java launcher. When we run again all tests then we will see that in first two cases it was but in third it wasn't. It will be text like following:








  

Usually last three lines are repeated many times.
...
So let's think over our results:

It's very easy to make working program from java classes or beans and it doesn't matter how fast it is unless you write commercial product. So, in last case, you should take care of garbage collection. If you build your program from limited number of class instances ( maybe there will 100s of them but limited number ) you will not get your program working crawled. Beware that big part of Java Platform core API (especially high level ) isn't designed with object reusability in mind. So if you will rely on this part you will not get it worked fast ( or very fast at least ).

For example , each call to int read() method of InputStreamReader ( which reads one character ) will produce garbage of array char[1] , another good example is class String, it is constant and if you are using many intermidiate Strings against the char[] only for the reason of their better usability you are fated to be slow see tests, you are urged to make new instance of GregorianCalendar to now about time each time and so on.

You might ask why it doesn't do the proposed object reusability way, I think there many reasons of it, one big reason that if you using reusable objects then you need take care of thread sharing ( synchronizing, etc ) and constant objects haven't such problem another reason that they rely on garbage collection. It will very useful for program speed to subclass all used core API classes in efficient manner, but if anyone will do it, then it might be better to rewrite core API to save time and remove rumor that Java is slow.

If someone isn't good programmer then it will not have fast program just by the reason that he uses assembler.It's possible to write fast programs using Java but one should use right object allocation and usage, trying to simplify (in ideal it should idle all program working time) the life of garbage collector :))), and then using right JIT (e.g. Symantec one for Win32) program will be faster even then many the same in C++. I've already seen such examples.

Below there are three links which contains example of using this concept. Here is excerpt of first tutorial. If you find my article useful then you'll find them too.

When I first implemented object pooling (specifically for database connections) into a real-time, multi-user application, average transaction times dropped from 250 milliseconds to 30 milliseconds. Users actually noticed and commented on the drastic increase in performance.
Build your own ObjectPool in Java to boost app speed
Improve the robustness and performance of your ObjectPool

Following article is elegantly repeat this conception in accurate way.
Java performance programming,Part 1: Smart object-management the day

Here is interesting fact of java VMs

When I've tested the speed of different Java VMs (for Win32) I've got interesting results. Here is results of testing different VMs, MS Java VM was acknoledged as fastest implementation in testing JMark 2.0 but I'm convinced that it has ( by means of JRI ) fastest garbage collection implementation and average JIT and it works fast because it less slows down the execution, Sun Java VM with Symantec JIT is performing 50% better in absence of garbage collection I've tested this statement using highly computative tests that aren't present here.

My best wishes for your fast Java programs :))).


Mail me your comments
Page hits:

This page hosted by Get your own Free Home Page

Last updated 11.28.1999 16.08 GMT+03