6

I use JMH to specify the complexity of the operation. If you've never worked with JMH, don't worry. JMH will just launch the estimateOperation method multiple times and then get the average time.

Question: [narrow] will this program calculate Math.cbrt(Integer.MAX_VALUE) each time? Or it just calculate it once and return cached result afterwards?

@GenerateMicroBenchmark
public  void estimateOperation() {
    calculate();
}

public int calculate() {
    return Math.cbrt(Integer.MAX_VALUE);
}

Question: [broad]: Does JVM ever cache the result of the methods?

VB_
  • 45,112
  • 42
  • 145
  • 293

4 Answers4

10

The method return value is never cached. However, unnecessary calls may be eliminated by JIT compiler in run-time due to certain optimizations like constant folding, constant propagation, dead code elimination, loop invariant hoisting, method inlining etc.

For example, if you replace Math.cbrt with Math.sqrt or with Math.pow, the method will not be called at all after JIT compilation, because the call will be replaced by a constant. (The optimization does not work for cbrt, because it is a rare method and it falls to a native call which is not intrinsified by JVM).

apangin
  • 92,924
  • 10
  • 193
  • 247
  • I'm not quite sure I follow what you're talking about with the JIT optimizations... `Math.sqrt()` also delegates to a native call (from the code I'm looking at, at least), and I don't see why the JIT compiler couldn't also optimize `Math.cbrt()` in the same manner as `Math.sqrt()` -- the same technique should work in both cases. – awksp Jun 15 '14 at 21:08
  • @user3580294 These calls may or may not be optimized depending on JVM. If we talk about HotSpot (the most popular JVM included in OpenJDK and Oracle JDK), `Math.sqrt` will be optimized, because it is a [JVM intrinsic](http://en.wikipedia.org/wiki/Intrinsic_function), i.e. JIT compiler does not treat it like a method, but replaces the call with evaluation code in-line. `Math.cbrt` though is not a HotSpot intrinsic - it just was not made such because of its rarity and the absense of corresponding CPU instruction. – apangin Jun 15 '14 at 21:21
  • The call is not replaced with a constant. When I tested this, it called it every time. – Anubian Noob Jun 15 '14 at 21:27
  • @AnubianNoob How did you test this? I support OP in using [JMH](http://openjdk.java.net/projects/code-tools/jmh/) - it often gives you realistic results. – apangin Jun 15 '14 at 21:37
  • I ran it and checked the times. `for (int i=0;i – Anubian Noob Jun 15 '14 at 21:40
  • @AnubianNoob It's not an equivalent replacement. Try `(int) Math.pow(10000, 2)` – apangin Jun 15 '14 at 21:50
  • Sorry, that's what I did. I casted to int. – Anubian Noob Jun 15 '14 at 22:22
  • @AnubianNoob Still slow with `(int)`? Hmm. Works equally fast for me. Would you mind sharing the whole test? – apangin Jun 15 '14 at 22:33
2

No.

Simply put, Java does not cache method results, since methods can return different values every time.

Anubian Noob
  • 13,426
  • 6
  • 53
  • 75
2

Yes it will invoke that code everytime it is being called

public int calculate() {
    return Math.cbrt(Integer.MAX_VALUE);
}


public double calculate();
    Code:
       0: ldc2_w        #3                  // double 2.147483647E9d
       3: invokestatic  #5                  // Method java/lang/Math.cbrt:(D)D
       6: dreturn    

to have cache, simply replace that magic number by

private static final field

private static final double NUMBER = Math.cbrt(Integer.MAX_VALUE);
jmj
  • 237,923
  • 42
  • 401
  • 438
  • 2
    The bytecode does not explain anything. E.g. replace `cbrt` with `sqrt` and the method WILL NOT be called every time. The answer depends on the method being called and the environment. JIT optimizations ([inlining](http://en.wikipedia.org/wiki/Inline_expansion) + [constant folding](http://en.wikipedia.org/wiki/Constant_folding) + [intrinsics](http://en.wikipedia.org/wiki/Intrinsic_function)) may result in the call being eliminated and replaced with a constant. – apangin Jun 15 '14 at 20:39
  • @apangin so can you post your answer please? – VB_ Jun 15 '14 at 20:46
  • @V_B Sure. Added an expanded answer. – apangin Jun 15 '14 at 21:05
2

Answer to narrow question: It depends on the JVM implementation and how the code is interpreted.

Answer to broad question: No since, as Anubian also pointed out, methods can return different values on each call.

M A
  • 71,713
  • 13
  • 134
  • 174