Do java caches results of the methods
Asked Answered
A

4

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?

Adventist answered 15/6, 2014 at 20:15 Comment(1)
Where does calculate() come in?Monsoon
P
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).

Pasho answered 15/6, 2014 at 20:48 Comment(8)
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.Dewyeyed
@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, 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.Pasho
The call is not replaced with a constant. When I tested this, it called it every time.Uranium
@AnubianNoob How did you test this? I support OP in using JMH - it often gives you realistic results.Pasho
I ran it and checked the times. for (int i=0;i<Math.pow(10000,2);i++) took WAY longer than for (int i=0;i<10000*10000;i++).Uranium
@AnubianNoob It's not an equivalent replacement. Try (int) Math.pow(10000, 2)Pasho
Sorry, that's what I did. I casted to int.Uranium
@AnubianNoob Still slow with (int)? Hmm. Works equally fast for me. Would you mind sharing the whole test?Pasho
U
2

No.

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

Uranium answered 15/6, 2014 at 20:18 Comment(0)
R
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);
Roberts answered 15/6, 2014 at 20:23 Comment(3)
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 + constant folding + intrinsics) may result in the call being eliminated and replaced with a constant.Pasho
@Pasho so can you post your answer please?Adventist
@V_B Sure. Added an expanded answer.Pasho
B
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.

Burkle answered 15/6, 2014 at 20:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.