2

Is there a way to achieve JIT performance while removing JIT overhead? Preferably by compiling a class file to an native image.

I have investigated GCJ, but even for a simple program, GCJ output's performance is much worse than Java JIT.

  • 6
    If you run the program long enough the JIT overhead will be minimal... and one advantage of JIT is that it takes your usage into account, recompiling your method several times if needed. You can't do that at compile time. – assylias Jun 03 '13 at 00:13
  • 1
    Is writing in C an option? :) That would definitely kill the JIT's overhead... And if you must execute it from Java, there are simple ways to invoke native libraries... – Petr Janeček Jun 03 '13 at 00:16
  • Thank you very much Assylias and Slanec. After reading some relevant topics, JNI (or invoking an native program) seems to be a better option. –  Jun 03 '13 at 00:17
  • 1
    Note that GCJ isn't really a Java compiler at all. Due to its reliance on the doomed GNU CLASSPATH project (which you should note isn't described as 'Java' anywhere and can never have passed The Java Compatibility Tests), it is a compiler for an increasingly small subset of Java that doesn't even include all of 1.2. There are other Java-to-native compilers out there. – user207421 Jun 03 '13 at 00:18
  • 2
    @Slanec although calling c from java might actually be slower: JNI has an overhead too. – assylias Jun 03 '13 at 00:20
  • 1
    By now the JVM has undergone many optimization cycles and many updates. If you truly believe that you will be able to achieve meaningful performance gains through native method calls, then you may find that your time investment has a smaller rate of return than you had hoped. In Effective Java, Joshua Bloch suggests that gains in performance are the least important reason to write native methods. – scottb Jun 03 '13 at 01:06
  • 1
    @HowardGuo Also, may I kindly ask what is your use case? As a student, I am very interested in real life examples of this. Do you need realtime behaviour without GC pauses (or at least predictable pauses)? Or is the JIT overhead seriously hurting the performace of your application for a different reason? Is the compilation taking too long? Did you try some of the [JVM options](http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html)? – Petr Janeček Jun 03 '13 at 11:20
  • Thanks for your interest Slanec.I develop a bunch of web applications, unfortunately their responsiveness is unacceptable after a server restart (which happens more often than I would like it to). Rather than warming them up by "using" the site myself, I would like to seek an alternative solution, perhaps by tweaking JIT behaviours. –  Jun 03 '13 at 12:20
  • There are some other projects (CPU intensive applications interact with databases) which I worked on show similar phenomenon, I am not sure whether JNI or native program can help, I will give them a try. –  Jun 03 '13 at 12:24
  • 1
    JNI overheads can by far exceed JIT overheads if you pass a lot of data back and forth. – Dmitry Leskov Jun 04 '13 at 05:52

5 Answers5

3

You could try Excelsior.

http://www.excelsior-usa.com/jet.html

I've had good experiences with this in the past (but it was a long time ago)

PaulM
  • 113
  • 5
2

There have been in the past a number of "static" compilers for Java, but I don't know that any are currently available. To the best of my knowledge the last one in use was the "Java Transformer" for the IBM iSeries "Classic JVM", but that JVM was deprecated in favor of the J9 JVM.

The "Java Transformer" did quite well, but, as others have noted, it could not take advantage of all of the info that a JITC has available at runtime (though it did manage to take advantage of some of the runtime info).

(And it should be noted that "JITC overhead" is really minimal. Compilation occurs pretty quickly and efficiently in most cases. The problem is that compilation doesn't even start until the interpreter has run long enough to collect statistics and trigger the JITC.)

Hot Licks
  • 47,103
  • 17
  • 93
  • 151
2

The simplest solution is often to warmup your code on startup. If you have a server based application, the cost of startup isn't as important as the cost when the service is used. In this situation you can warmup all the critical code by calling it 10K - 20K times which triggers all that code to compile.

This can take less than a second in simple cases so has very little impact on startup and means you are using compiled code when the service is used.

If you have a client based application you usually have a lot of processing power for just one user in which case the cost of the background JIT is less important.

The moral of the story is; try to check you have a problem to solve before diving into a solution. Very often questions on stack over flow are about problems which have either a) already been solved or b) are not a significant problem in the first place.

Measuring the extent of your problem or performance is the best guide as to what matters and what doesn't. If you don't measure, you are just guessing. (Even if you have ten+ year experience performance tuning Java systems)

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
0

I have just found my answer here:

Why is Java faster when using a JIT vs. compiling to machine code?

Quote from top answer:

This means that you cannot write a AOT compiler which covers ALL Java programs as there is information available only at runtime about the characteristics of the program.

Community
  • 1
  • 1
0

I'd recommend you to find the root cause of inferior performance of your Java code before trying out AOT compilation or rewriting any portions in C++.

Head over to http://www.javaperformancetuning.com/ for tons of information and links.

Dmitry Leskov
  • 3,233
  • 1
  • 20
  • 17