2

Is there some way to get reasonable (not noticeable) starting times for Java, thus making it suitable for writing command line scripts (not long-lived apps)?


For a demonstation of the issue, take a simple Hello World program in Java and JavaScript (run w/ node.js) on my Macbook Pro:

$ time java T
Hello world!

real    0m0.352s
user    0m0.301s
sys 0m0.053s

$ time node T.js
Hello world!

real    0m0.098s
user    0m0.079s
sys 0m0.013s

There is a noticeable lag with the Java version, not so with Node. This makes command line tools seem unresponsive. (This is especially true if they rely on more than one class, unlike the simple T.java above.

Aaron Yodaiken
  • 19,163
  • 32
  • 103
  • 184
  • Java runs in a virtual machine. JavaScript is executed straight from the code. Try timing either larger programs (smaller overhead) or only the execution time (no virtual machine lag). – Hidde May 16 '12 at 22:30
  • 2
    You may want to read about Java Quick Starter: http://www.java.com/en/download/help/quickstarter.xml and http://www.javalobby.org/java/forums/t102150.html – Guillaume Polet May 16 '12 at 22:30
  • 1
    Java *isn't* suitable for writing command-line scripts. There are many other languages better suited it. Use the appropriate tool for the job. – skaffman May 16 '12 at 22:37
  • @GuillaumePolet Trying to write code primarily for OSX/Unix, but thanks. – Aaron Yodaiken May 16 '12 at 22:39
  • @skaffman Unfortunately, there are many libraries for which the best interface is Java, e.g. ANTLR (I know that there are C-target options, but it is not kept in sync with the code and is sort of Java-in-C style code.) – Aaron Yodaiken May 16 '12 at 22:40
  • @HIdde I'm not trying to say that Java has worse performance than JavaScript, and I'm aware that it's in a VM. I'm trying to find a way to get better _startup_ performance (perhaps by keeping a VM around or something). – Aaron Yodaiken May 16 '12 at 22:42
  • @luxun Have you looked into Mono? It starts up for me in 1/4 the time of java on my OS X machine. – Andrew T Finnell May 16 '12 at 22:51
  • @luxun I read the timings incorrectly. Mono starts in 1/10 the time of Java in trival cases for me. – Andrew T Finnell May 16 '12 at 22:59
  • I (unfortunately in this regard) need to use Java for this project, I believe. – Aaron Yodaiken May 16 '12 at 23:24
  • possible duplicate of http://stackoverflow.com/questions/4056280/anyway-to-boost-java-jvm-startup-speed – rogerdpack Nov 03 '12 at 13:57
  • possible duplicate of [How to speed up Java VM (JVM) startup time?](http://stackoverflow.com/questions/1491325/how-to-speed-up-java-vm-jvm-startup-time) – user7610 Nov 25 '14 at 21:43

5 Answers5

3

Not likely, only thing you might be able to try is a different implementation of the JVM, but that probably won't change. Most Java apps are (relatively) long lived though and possibly interactive, which means the JVM startup time becomes lost in the noise of normal uses.

Drizzt321
  • 993
  • 13
  • 27
1

Have you actually tried timing a Java command-line app called repeatedly, though? I would expect after the first incarnation for the start-up time to be alleviated somewhat by the library classes being in the file system cache.

That said, yes, the Java platform is not one of the simplest and in any case you're not going to compete with a small native executable.

Edit: as you say that the timings above are for "warmed up" calls, then a possible workaround could be:

  • write the gubbins of your commands in Java
  • write a simple local continually running "server" that takes commands and passes them to the relevant Java routines
  • write a simple native command-line wrapper (or write it in something that's fast to start up) whose sole raison d'être is to pass commands on to the Java server and spit out the result.

This ain't nice, but it could allow you to write the gubbins of your routines in Java (which I assume is essentially what you want) while still keeping the command line model of invocation.

Neil Coffey
  • 21,615
  • 7
  • 62
  • 83
  • Yes, I have—the first run generally takes about _3.5_ seconds, followed by timing shown above for the subsequent runs for a Hello Word. – Aaron Yodaiken May 16 '12 at 22:38
  • Ah, OK. Now I look at your timings again, a third of a second actually isn't so bad for a Java startup. If you really need it faster, then I've amended my answer to suggest a kludgy workaround. – Neil Coffey May 16 '12 at 22:51
1

As others have said, the plain answer is just "not really". You can possibly make minor performance improvements, but you're never going to get away from the fact that the VM is going to take a while to start up and get going.

Make sure you haven't got the server VM selected for apps like this - that's one thing that really will increase the start up time.

The only real way round it is to compile Java to native code, which you can do with GCJ - so if you must write these apps in Java and you must have them faster, that might be a route to look down. Bear in mind though it's not that up-to-date and maintenance on it largely seems to be dying out too.

Michael Berry
  • 70,193
  • 21
  • 157
  • 216
1

Haven't tried it yet but might be worth looking at nailgun. It will run your Java programs in the same JVM, so after "warming up" should be pretty fast. A "hello world" example goes from taking 0.132s to taking 0.004s

http://www.martiansoftware.com/nailgun/background.html

OneSolitaryNoob
  • 5,423
  • 3
  • 25
  • 43
0

You can get a small speed-up with class data sharing https://rmannibucau.metawerx.net/post/java-class-data-sharing-docker-startup

A much bigger speedup should come from doing ahead-of-time compilation to a static binary using GraalVM native-image, although it's still tricky to use. A lot of libraries haven't been made compatible.

Aleksandr Dubinsky
  • 22,436
  • 15
  • 82
  • 99