2

Can the JVM optimize this code

How does this code get optimized in the Java compiler or JVM, I am asking specifically for optimization done if this such code was written java

Stream.of(1, 2, 3)
      .map(i -> i + 1)
      .map(i -> i + 1)
      .map(i -> i + 1);

to something like

Stream.of(1, 2, 3)
      .map(i -> i + 3)

or be even more aggressive and replace this with a basic for loop which could possible improve performance.

In clojure there is a concept of transducer which is a sort of optimization that you can do to compose reduce-able functions into a single function and remove the overhead of lazy propagation. Can the JVM transduce some functions in a fluent api?

for instance if we had a decorator interface for Java streams

decor-map(decor-map(base-map (i -> i + 1), i -> i +1), i -> i + 1)

then I assume that the compile could somehow try to transduce the decorator maps. But how is this possible in a fluent api?

saurabh kumar
  • 332
  • 1
  • 8
  • Clojure is a JVM language too. Do you mean "how does the Java compiler optimize that code"? – ernest_k Feb 06 '19 at 06:00
  • 1
    @ernest_k The Oracle/OpenJDK Java compiler doesn't usually do a whole lot of optimization, opting instead to have it done at the JVM level, during JIT. It's not at all unreasonable that the JVM would do these kinds of optimizations, either now or in a future release. – yshavit Feb 06 '19 at 06:05
  • @yshavit I understand that. My question was to clarify whether the OP was rather asking about compile-time optimizations. – ernest_k Feb 06 '19 at 06:08
  • 1
    @ernest_k Ah ok, sorry. I thought you were implying that _only_ the Java compiler could do it. :-) – yshavit Feb 06 '19 at 06:12
  • edited my question. I am interested in how this code is optimized by Java and then by JVM – saurabh kumar Feb 06 '19 at 06:25

1 Answers1

2

Javac really doesn't do much optimization, to my knowledge, it really only does constant folding.

In other words: all the sophisticated optimization options that many other languages, such as C++ directly apply when compiling source code into machine code ... javac doesn't do any of that.

Why: because that happens (where it makes sense) at runtime, by the JIT.

Conclusion: you don't worry about the performance for Java code on the "source code side of things". You try to write easy simple code, with short methods, so that the JIT can do it magic and inline all of that, and turn it into machine code that is optimized to support your actual usage patterns.

it4Astuces
  • 432
  • 5
  • 17
GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • so to JIT fluent api looks just like simple function calls and it can optimize them using the same rules? – saurabh kumar Feb 06 '19 at 18:57
  • 1
    I actually doubt the JIT would do that today; my understanding is that they're basically in "more features" mode right now, and will worry about small optimizations like this until later (one advantage of optimizing in the JIT: your classes will get those new optimizations without having to be recompiled!). But as always, if you're worried about three `i + 1` calls, your first step should be not to worry about them. Your second step should be to measure your _whole_ application to see if those extra couple calls are really causing you any noticeable slowdown. – yshavit Feb 06 '19 at 19:01
  • 1
    @yshavit True. I tried to express that "you are looking for performance in the wrong place" in the last paragraph but maybe I should make that more explicit. – GhostCat Feb 06 '19 at 19:39