Hello,
I'm reminded of Professor Knuth's observation that "Premature
optimization is the root of all evil."
If from an API perspective the new code is preferable, I would say that
should take precedence over an at most marginal performance degradation.
If performance of is a high concern in that area, perhaps a jmh
experiment could help tease about the difference in speed.
-Joe
On 04/27/2014 04:08 PM, Richard Warburton wrote:
Hi,
There are multiple possible targets for invokevirtual
position:(I)Ljava/nio/Buffer; - all the methods that override it in all
subclasses loaded. It doesn't matter if they are final or not (only if
they are effectively final or not). The non-finality of a method has a
performance impact only if the method *is* overridden in any of the
loaded subclasses, otherwise it is effectively final and treated as such
by JIT (at least that's how I understand it - any hotspot JIT expert
please debunk my claims).
That is only true if you are calling the method on the base class, which
is normally seldom done (though it will be nearly always in legacy code,
but see below).
That might also be the answer to why the synthetic method need not be
marked as final if the covariant method is. The synthetic method can
never be overridden in a sub-class (at least not by javac) - only the
covariant method can be.
Doesn't sound quite right to me, but I'll defer to any experts who might
wish to discuss it on compiler-dev.
But as Paul noted, the methods on Buffer are probably not used in hot
loops alone, since they are just for reading/adjusting
position/limit/mark. The hot loops probably also contain methods for
reading/writing the buffer and those are only defined on particular
sub-types of java.nio.Buffer, so it can reasonably be expected that the
static (guaranteed) type of target upon which methods are called in hot
loops is a particular subtype of java.nio.Buffer and JIT only has one
method to choose from in this case.
Yeah new code will call the covariant final method directly in almost all
cases for sure, having been compiled against it. The tricky case is old
code - even if the JIT can figure out that it is really a subclass being
invoked upon, it'd still be forced to target the non-covariant synthetic
method due to the specific method reference in the bytecode. Hopefully at
this point though, as you say, the lack of overriding classes will be
enough to optimize the dispatch.
So interestingly the original patch didn't add final to the covariant
overrides. I've updated the patch to do this.
http://cr.openjdk.java.net/~rwarburton/buffer-overrides-1/
I'm not sure what would satisfy people on the performance front. Some
guidance would be most appreciated here.
regards,
Richard Warburton
http://insightfullogic.com
@RichardWarburto <http://twitter.com/richardwarburto>