There is a lot in this code to "learn" from. You can/should obviously use 
something like jmh to save you much of the trouble of making these mistakes. 
But if you want to learn about the various mistakes that people commonly make 
when trying to measure stuff, this code is a good starting point. It is a 
classic "how not to micro-benchmark" example and a good teaching/learning 
opportunity. So if we change the title from "Why a Java method invocation is 
slower..." to "Why does measuring like this give me the wrong impression 
that...", and putting aside style comments, here are some comments and 
highlights of likely reasons of why you are seeing a bigger number for the time 
elapsed in your single invocation from a second call site compared to the 
1,000,000 invocations from the earlier call site:

- The first call site does not warm up the method. It warms up the call site. 
"Warmup" is not a proper term fir what you are doing there... The method can be 
(and likely was) inlined into the call site and optimized there.

- When the second call site is invoked once, it May not have been inlined there 
yet, and may be calling interpreted or lower tiered optimization versions of 
the method. If excercized enough, the second call site would likely inline as 
well.

Separately interesting:

- Your mySleep won't actually do what you think it does. The entire method can 
be optimized away to nothing after inking at the call site by the JIT once the 
calls to it actually warm up enough, since it has no side effects and nothing 
is done with its return code.

- Your while(true) loop in the code and the output don't seem to match. Where 
is rest of the output? Or is this output from an earlier code version without 
the while(true) loop?

- You are accumulating more and more contents into an array list. At some point 
the arraylist will be resized. That does not yet happen in your specific run 
(1,000,000 iterations plus 1 still fits in the initial 2^20 size), but if you 
did keep running... if you want to measure while excercizing a large data 
structure like this, I'd initialize it all and then wrap around it (with some 
modulu of length) rather than keep accumulating.

And last, calls to the same Java method at different sites *can* end being 
slower or faster depending on many factors. For example, when inlined at the 
call sites, the parameters passed may effect the optimizations possible, and 
may vary depending on call site. More importantly, whether or not a method is 
inlined is call-site dependent. E.g. some inlining depth or overall calling 
code size threshold may have been exceeded to stop inlining in one site but not 
in another.

-- 
You received this message because you are subscribed to the Google Groups 
"mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to