Thanks Kris, good to know.  As much as instanceof checks are usually a code
smell, it sure would be nice if the interface version could be optimized
somewhat (at least for shallow hierarchies).

Cheers

Sent from my phone
On May 24, 2012 10:41 PM, "Krystal Mok" <rednaxel...@gmail.com> wrote:

> Hi Mike,
>
> On Fri, May 25, 2012 at 10:12 AM, Mike Duigou <mike.dui...@oracle.com>wrote:
>
>>
>> On May 24 2012, at 16:32 , Vitaly Davidovich wrote:
>>
>> > That's a bit odd as I thought the Klass object in the VM stored
>> something like 7 supers, which includes interfaces (if I'm not mistaken).
>>  I know that instanceof checks against final classes are optimized into a
>> simple cmp against an address, but I'm surprised that a check against an
>> interface for classes in a very shallow type hierarchy is up to x25 slower.
>>  Do you know why that is Mike? Did you ask the compiler guys by chance?
>> >
>> I didn't actually look much further into it other than to write a small
>> microbenchmark to make sure it was the instanceof check. I tested a couple
>> of different configs of classes and interfaces and supers. I was able to
>> validate that 'x instanceof String'  was as fast as 'x.getClass() ==
>> String.class' and that other cases were slower. Inheritance checks seemed
>> faster than checks on interfaces. That was enough to tell me that I was on
>> the wrong track with 'x instanceof Hashable' as a way to determine which
>> hash algorithm to use. At least for C2 server compiler.
>>
>> FYI, "x.getClass() == String.class" will be just as fast when 7170463 [1]
> is in.
>
> @Vitaly
>
> The fast subtype checking algorithm in HotSpot treats interfaces as
> "secondary supers", which goes through a slow path. The super type display
> in instanceKlass is only for "primary supers", which does not include
> interfaces for instance classes. You may want to check out the details in
> this paper [2].
>
> > Definition 5:  A class T is a secondary type iff T is an interface or
> > an array of a secondary type. Every type is either a primary
> > type or a secondary type but not both.
>
> Regards,
> Kris
>
> [1]:
> http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/2012-May/007730.html
> [2]: http://dl.acm.org/citation.cfm?id=583821
>
>
>> If there is a thorough exploration or explanation of which dispatching
>> techniques have good performance and an explanation of which idioms will
>> never be fast I'd be interested to read it.
>>
>> Mike
>> > Thanks
>> >
>> > Sent from my phone
>> >
>> > On May 24, 2012 5:26 PM, "Mike Duigou" <mike.dui...@oracle.com> wrote:
>> >
>> > On May 23 2012, at 16:31 , David Holmes wrote:
>> >
>> > > On 24/05/2012 2:24 AM, Mike Duigou wrote:
>> > >> Hi Mike;
>> > >>
>> > >> The problem with using instanceof Hashable32 is that is much slower
>> (often more than 25X) than instanceof String. It's slow enough that we
>> won't reasonably consider using instanceof Hashable32 in JDK 8. We have
>> considered making Object implement Hashable32 and add a virtual extension
>> method to Object for hash32(). The extension method would just call
>> hashCode(). A compiler that supports extension methods is not yet part of
>> the JDK mainline repo yet (It is still in the Lambda repo). This approach
>> would mean that we can avoid an instanceof check but there is a *lot* of
>> entirely reasonable reservations about having Object implement an interface
>> and gain a new method.
>> > >
>> > > Is it worth using:
>> > >
>> > > && (k instanceof String || k instanceof Hash32)
>> > >
>> > > to deal with that. What would be the penalty on non-String Hash32's?
>> >
>> > The problem in this case would be the k instances that are neither
>> String nor Hash32. They would be severely impacted. Using Doug Lea's
>> "loops" Map microbenchmark, "k instanceof Hash32" was up to 25 times more
>> expensive than calling "k instanceof String". I suspect that it could be
>> even higher with classes that have deep inheritance hierarchies. My
>> non-Hash32 keys were all instances of Number (Float, Double, Integer and
>> Long) so each had a single interface.
>> >
>> > Mike
>> >
>> > > David
>> > >
>> > >> Opinions and insights welcome,
>> > >>
>> > >> Mike
>> > >>
>> > >> On May 23 2012, at 00:38 , Mike Skells wrote:
>> > >>
>> > >>> Hi Mike,
>> > >>>
>> > >>> I have a query, why is this implementation limitted to String?
>> > >>> Is this by intent?
>> > >>>
>> > >>> in HashMap the patch for hash calculation is
>> > >>>  290     final int hash(Object k) {
>> > >>>  291         int h = hashMask;
>> > >>>  292         if ((0 != h)&&  (k instanceof String)) {
>> > >>>  293             return h ^ ((String)k).hash32();
>> > >>> ....
>> > >>> whereas I would have thought that it should be
>> > >>>  290     final int hash(Object k) {
>> > >>>  291         int h = hashMask;
>> > >>>  292         if ((0 != h)&&  (k instanceof Hash32)) {
>> > >>>  293             return h ^ ((Hash32)k).hash32();
>> > >>> ....
>> > >>>
>> > >>> As a more flexible improvement could you supply a HashCode and
>> Equals delegate, and then the user can supply either a custom delegate,
>> suitable for that application (e.g.one that iterates through array content,
>> or any other application data structure that needs to be handled
>> differently like c# uses
>> http://msdn.microsoft.com/en-us/library/system.collections.iequalitycomparer)
>> > >>>
>> > >>> Regards
>> > >>>
>> > >>> Mike
>> > >>
>> >
>>
>>
>

Reply via email to