2006-01-25

Are we ready to replace /bin/true?

I've been talking about re-implementing someone else's C program in Java recently. A friend reminded me that I wouldn't be able to use the Java replacement in the same way as I use the C original, which is invoking it as a subprocess via ProcessBuilder.

Now that's okay, and not the point, because part of the reason for re-implementing the C program would be so we could use it as a library rather than as a separate program, and avoid all the I/O associated with the C program, and all the code on both sides associated with the interchange file format.

But I was still curious. I know that putting a window on the screen is the kiss of death as far as start-up time goes for a Java program, but how does "Hello, World!" compare these days?

Here are the three programs I used:

hydrogen:~$ cat x.c
#include
#include
int main(void) {
printf("Hello, World!\n");
exit(0);
}
hydrogen:~$ cat x2.cpp
#include
#include
int main(void) {
std::cout << "Hello, World!\n";
exit(0);
}
hydrogen:~$ cat x3.java
public class x3 {
public static void main(String[] args) {
System.out.print("Hello, World!\n");
System.exit(0);
}
}
hydrogen:~$


First Mac OS 10.4.4 on the dual G5, running Java 1.5.0_06 (this is the last of several runs):

hydrogen:~$ time ./x ; time ./x2 ; time java x3
Hello, World!

real 0m0.006s
user 0m0.001s
sys 0m0.005s
Hello, World!

real 0m0.006s
user 0m0.001s
sys 0m0.005s
Hello, World!

real 0m0.211s
user 0m0.123s
sys 0m0.077s
hydrogen:~$

The interesting thing there is that the C program is no faster than the C++ program. This doesn't tend to be true of trivial programs on Linux, because the C++ program will involve more shared libraries, and that leads to a longer start-up time.

Now Ubuntu (Linux 2.6.12-10) on the Opteron, running Java 1.5.0_06 for x86 and for amd64:

helium:~$ time ./x
Hello, World!

real 0m0.001s
user 0m0.000s
sys 0m0.002s
helium:~$ time ./x2
Hello, World!

real 0m0.003s
user 0m0.001s
sys 0m0.002s
helium:~$ time /usr/local/jdk/jdk1.5.0_06/bin/java -cp ~ x3
Hello, World!

real 0m0.154s
user 0m0.065s
sys 0m0.009s
helium:~$ time /usr/local/jdk/jdk1.5.0_06-amd64/bin/java -cp ~ x3
Hello, World!

real 0m0.211s
user 0m0.134s
sys 0m0.011s

There we see that C++'s extra shared libraries cause it to start very slightly slower, and that the x86 JVM's client compiler lets it start significantly quicker than the amd64 JVM's server compiler. (The amd64 JVM doesn't have a client compiler.) Both JVMs are well behind the C++ program, though.

So although these are respectable times compared to the early days, and they're not important when you're talking about interactive programs or servers, you still wouldn't want the Ruby interpreter rewritten in Java, let alone something like /bin/true.