If you get into reading Java byte code, the command javap -p -s -v -c -constants Something.class
will become quite handy.
Typically in a s.length()
scenario, you do a call on a different class, creating a different stack frame, which is used to evaluate that call.
In an int x = s.length()
scenario, you do that same call, but you do an additional call to store the integer within your stack frame at one of the frame storage locations.
This means that reusing the stored call becomes faster or slower based on a number of confounding factors.
- If you were going to call
s.length()
many times, you would have triggered the limit for hotspot's call optimization earlier, leading to even faster execution, after the s.length()
was compiled or inlined into your call stack.
- If
s.length()
is ridiculously slow or complex, or you are only going to call it a few times, then caching the value might provide the faster execution, because hotspot might refuse to optimize the call.
These are of course, rules of thumb I've developed after reversing / assembling / reading code and like all good rules of thumb, are nearly useless in a specific scenario. If you have a specific scenario, benchmark. There are many "ifs" in both observations #1 and #2, and most of the time I don't realize which ones are in play without benchmarking.
With that in mind, in general, and especially prior to any hotspot triggered optimization, the smaller the number of bytecode operations in a method, generally the faster it runs. Also, stack frames are (pre-optimization) more expensive that you might be inclined to think (CPU wise), but hotspot does a great job of mitigating that cost for the most heavily used invocations.