Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to reduce startup time of a console Java application?

I noticed that the startup time of a minimal console application in Java is slightly more than 100 ms on my machine compared to 1 ms of an equivalent C application. Although it is not a problem in most cases I would like to find out if there is a way to reduce this time because I need to write an application that will be executed many times (say in a loop within a bash script).

like image 624
vitaut Avatar asked Oct 26 '10 07:10

vitaut


3 Answers

You asking for the "Achilles' heel" of Java. There is really not much to do with it. The last Java version will be the most performant, they are working for years on that issue.

Anyway running the same program several times you will notice that after first startup the next is much more faster. I think that comes from the OS caching mechanism.

The only real way to make it better is to let run your app in background and comunicate with your app maybe thru a web service (that is what servelet container is all about).

100ms not sounds too much but could be unacceptable in your case.

like image 95
PeterMmm Avatar answered Sep 20 '22 03:09

PeterMmm


So here are some details about the solution I used.

Starting from this trivial program (HelloWorld.java) which took about 100ms to execute:

class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, world!");
   }
}

$ javac HelloWorld.java
$ time java HelloWorld
Hello, world!

real    0m0.109s
user    0m0.030s
sys     0m0.030s

I converted it into a trivial server:

import java.io.*;
import java.net.*;

class HelloWorldThread extends Thread {
    private Socket socket;

    public HelloWorldThread(Socket s) {
        super("HelloWorldThread");
        socket = s;
    }

    public void run() {
        try {
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            out.println("Hello, world!");
            out.close();
            socket.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class HelloWorld {
    public static void main(String[] args) {
        try {
            ServerSocket serverSocket = new ServerSocket(30281);
            while (true)
                new HelloWorldThread(serverSocket.accept()).start();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}

start it once and use netcat to connect to it (thanks PeterMmm for the idea) which resulted in the execution time of just 3ms:

$ javac HelloWorld.java
$ java HelloWorld &
$ time nc localhost 30281
Hello, world!

real    0m0.003s
user    0m0.000s
sys     0m0.000s
like image 20
vitaut Avatar answered Sep 20 '22 03:09

vitaut


Compile your code to native code using GCJ. Will help a little, don't expect too much though.

like image 43
Steve-o Avatar answered Sep 20 '22 03:09

Steve-o