1

I am using the following line of code over and over in a loop:

Object val;
while (logic())
   val = val == null ? generateObj() : val;

I am curious how the JVM optimizes this code, if at all? I.e., if val != null will the JVM sense that the assignment goes back to self and just ignore the rest of the line, or will it take the time to copy the reference of val back over itself?

I am running the standard JRE 6 and JRE 7 in my environments for Windows 7.

ASIDE: If the JVM does not optimize this operation very well, what is the best alternative to doing this call? Just if (val == null) val = generateObj();?

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152
E.S.
  • 2,733
  • 6
  • 36
  • 71
  • 6
    Any reason (beside curiosity) you didn't write `if (val != null) val = generateObj();`? – Adriano Repetti Apr 22 '14 at 20:56
  • No, no. This question is about how Java works. I should have added "What would be the best alternative if the JVM does not optimize this" – E.S. Apr 22 '14 at 20:58
  • 3
    If the JVM doesn't optimize it, your best option is to totally disregard that lack of optimization and write whatever code is clearest to a human. I would be _shocked_ if that extra write -- to a local field, no less -- were measurable in the grand scheme of your application, let alone a significant portion of your running time. – yshavit Apr 22 '14 at 21:05
  • 1
    Won't compile because `val` not assigned. – Hannes Apr 22 '14 at 21:06
  • 6
    These sorts of microoptimizations are almost never worth it unless you have quantifiable data justifying that the cost of the much cleaner `if` statement adriano pointed out is too slow. It just makes the code harder to read, harder to maintain, and more error-prone. – templatetypedef Apr 22 '14 at 21:11
  • If you are going to write code like this at least put parentheses around the ternary, so `var=(var==null ? go() : var);` When I first read this I thought you were setting var to a boolean – Richard Tingle Apr 22 '14 at 21:16
  • Lots of comments are along the lines of "there is no point in doing this" but that misses the point of the question. I just want to know what the JVM can do to optimize it. This is an academic question. – E.S. Apr 23 '14 at 00:30
  • I'm on mobile now, so no full answer, but try disassembling this code with `javap`. – chrylis -cautiouslyoptimistic- Apr 23 '14 at 10:02
  • @chrylis The question is explicitly about 'how the *JVM* optimizes this code', not `javac.` – user207421 Apr 23 '14 at 10:09
  • @EJP The question uses terminology loosely, and asking about the JVM is moot if a "modern Java" compiler has already eliminated unnecessary code. – chrylis -cautiouslyoptimistic- Apr 23 '14 at 10:17

2 Answers2

1

Java is an interpreted language. Java mainly optimizes at runtime. The generated bytecode is in general completely unoptimized. Only when the JVM executes the bytecode it will start optimizing, depending on how your code will be executed. So it might be that the JVM does not optimize anything if your loop just runs a couple of times. You can never definitely say whether the JVM will optimize something or not. It will also depend on the concrete JVM implementation. So you should never rely on that.

Jan Schaefer
  • 1,882
  • 1
  • 18
  • 23
  • 2
    It's worth noting that often the java bytecode isn't interpreted but is [JIT compiled to machine code](http://stackoverflow.com/questions/1326071/is-java-a-compiled-or-an-interpreted-programming-language) – Richard Tingle Apr 22 '14 at 21:25
  • There are plenty of optimizations the compiler can make well before the JVM sees the bytecode. – chrylis -cautiouslyoptimistic- Apr 23 '14 at 10:01
  • @chrylis There are indeed, but `javac` doesn't make many of them. – user207421 Apr 23 '14 at 10:07
  • @RichardTingle yes you are right, however, initially the bytecode is typically only interpreted. Only when the JVM decides that it is worth to JIT-compile, it will do so. – Jan Schaefer Apr 25 '14 at 11:01
1

Curious? Pick some JVM (list of them is available here: http://en.wikipedia.org/wiki/Java_Virtual_Machine) with source code open and go debug output of the JIT compiler.

I don't know if internals of the Oracle JVM in particular (the one you're probably running on Windows) went open source, but perhaps their engineers might answer your question clearly, especially if you file in a performance-problem ticket (I used to solve this kind of tickets for Symbian JVM (there 2 of them) and we had tools to diagnose this kind stuff in detail).

In general the question how modern Java optimizes something does not have general simple answer. IMHO best way to learn more is to go pick one and play with it (run benchmarks, study traces etc.)

If you're asking how to write better code then this - super cool Stack Overflow answer - can give you some hints

EDIT: Is there a guide to setting up the JDK to compile your java code from a C Compiler? (Ideally an eclipse set up)

Yes there should be one. Just be warned that working with larger software repositories (thousands of files and hundreds of thousands up to milions of lines of code) is usually not for the faint-hearted and to get the environment setup right (even with some documentation) can take some days.

Wikipedia - List of Java virtual machines lists some open source JVMs. The Oracle JVM page points to OpenJDK - the The HotSpot Group where you can find some (lots of) resources and guides, but mainly invaluable contacts to developers who should be able to help you get up and running.

(I can not provide you with more precise instructions as I'm out of the JVM and Symbian OS business for nearly 5 years and things had changed a bit...)

Community
  • 1
  • 1
xmojmr
  • 8,073
  • 5
  • 31
  • 54
  • Is there a guide to setting up the JDK to compile your java code from a C Compiler? (Ideally an eclipse set up) – E.S. Apr 23 '14 at 17:11