Covariant overrides on the Buffer Hierachy
joe.darcy at oracle.com
Thu May 1 00:20:16 UTC 2014
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.
On 04/27/2014 04:08 PM, Richard Warburton wrote:
> 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.
> I'm not sure what would satisfy people on the performance front. Some
> guidance would be most appreciated here.
> Richard Warburton
> @RichardWarburto <http://twitter.com/richardwarburto>
More information about the core-libs-dev