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).
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.
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
Compile your code to native code using GCJ. Will help a little, don't expect too much though.
And maybe java is not the best tool for the job? Using client-server approach just for performance reasons seems to me like a really bad idea. You introduce additional complexity and points of failure. What if server crashes or tcp port is already taken, etc?