instanceof vs class

H

hilz

Hi,

If i have an object o, is there a difference bewten the two tests below? If
so, is one of them more efficient than the other?

if(o instanceof SomeClass)

if(o.getClass()== SomeClass.class)


thanks
hilz.
 
S

Stefan Ram

hilz said:
if(o instanceof SomeClass)

Here, SomeClass might also be a class extended by the class of
the object o, or an interface implemented by that class, or an
interface implemented by a class extended by the class of o,
or an interface extending an interface that is ...
if(o.getClass()== SomeClass.class)

Here, not.
 
H

hilz

Stefan Ram said:
Here, SomeClass might also be a class extended by the class of
the object o, or an interface implemented by that class, or an
interface implemented by a class extended by the class of o,
or an interface extending an interface that is ...


Here, not.

Thank you Stefan.
Now if i guarantee that i am always testing against either
A) the same class as my object
or
B) a totally different class that is neither a super class of my object nor
an interface that my object implements

in this case, will the two tests be the same?
if so, then does one of them perform better that the other?
I kind of remember reading somewhere that "instanceof" has some overhead,
which makes it slower that the other option.
can anyone confirm that?

thank you
hilz.
 
M

Michael David Pedersen

Hi,

hilz said:
Hi,

If i have an object o, is there a difference bewten the two tests below? If
so, is one of them more efficient than the other?

if(o instanceof SomeClass)

if(o.getClass()== SomeClass.class)

I believe "o.getClass() == SomeClass.class" will be true exactly if o is an
instance of SomeClass. On the other hand, "o instanceof SomeClass" will also
be true if o is an instance of a subclass of SomeClass.

Regards,
Michael.
 
H

hilz

Will Hartung said:
Yes, a direct comparison using == will be faster than instanceof, but only
because instanceof will walk the class->superclass chain of the tested
object rather than simply fail.

For example:

public boolean instanceOf (Object o, Class c)
{
Class c2 = o.getClass();

while(c2 != null) {
if (c == c2) {
return true;
}
c2 = c2.getSuperclass();
}
return false;
}

So, obviously instanceof will be slower.

But why even worry about the speed of instanceof?

Also, note:

x = (SomeClass)y;

Incurs the same cost as instanceof.

So simply "yes it's faster", but I sure wouldn't ever worry about it unless
some profiler pointed it out as a smoking gun.

Regards,

Will Hartung
([email protected])

Thanks Will.
The code you provided was very helpful making me understand the difference.
now i can make my decision based on that.
this comparison is going to be used at a very low lever where it will be
repeated a huge number of times, and such a difference in bahavior will make
a difference in the performace of the application.

i definately need the direct class comparison using the == operator.

thank you very much.
hilz
 
W

Will Hartung

hilz said:
Now if i guarantee that i am always testing against either
A) the same class as my object
or
B) a totally different class that is neither a super class of my object nor
an interface that my object implements

in this case, will the two tests be the same?
if so, then does one of them perform better that the other?
I kind of remember reading somewhere that "instanceof" has some overhead,
which makes it slower that the other option.
can anyone confirm that?

Yes, a direct comparison using == will be faster than instanceof, but only
because instanceof will walk the class->superclass chain of the tested
object rather than simply fail.

For example:

public boolean instanceOf (Object o, Class c)
{
Class c2 = o.getClass();

while(c2 != null) {
if (c == c2) {
return true;
}
c2 = c2.getSuperclass();
}
return false;
}

So, obviously instanceof will be slower.

But why even worry about the speed of instanceof?

Also, note:

x = (SomeClass)y;

Incurs the same cost as instanceof.

So simply "yes it's faster", but I sure wouldn't ever worry about it unless
some profiler pointed it out as a smoking gun.

Regards,

Will Hartung
([email protected])
 
C

Carl Howells

hilz said:
Thanks Will.
The code you provided was very helpful making me understand the difference.
now i can make my decision based on that.
this comparison is going to be used at a very low lever where it will be
repeated a huge number of times, and such a difference in bahavior will make
a difference in the performace of the application.

i definately need the direct class comparison using the == operator.

Argh. I think that's wrong.

First, I think you're wrong about how much it matters. I'm betting that
doing it either way will result in less than a .5% speed difference in
the overall application. You can make up for more than that by doing
things better at a higher level.

Second, I'm not even convinced Will Hartung is correct about which one
is faster. I'm very certain that if you move between different versions
and vendors of the JVM, you will get differing results in any testing there.

Third, I think having to perform either test indicates a big design
flaw, which will have more of an impact on your performance than either
test ever could.
 
R

Roedy Green

Yes, a direct comparison using == will be faster than instanceof, but only
because instanceof will walk the class->superclass chain of the tested
object rather than simply fail.

On the other paw instanceof is a single JVM instruction, and may be
highly optimised or short circuited via optimisation versioning. But,
in theory it SHOULD take longer than a single class compare.

As always MEASURE if it matters.
 
H

hilz

Got it!
Thanks Roedy,
by the way.... how did that homework of yours go?! did you receive anything
by DHL the next day?!!!
:)
just kidding!
 
R

Roedy Green

On the other paw instanceof is a single JVM instruction, and may be
highly optimised or short circuited via optimisation versioning. But,
in theory it SHOULD take longer than a single class compare.

As always MEASURE if it matters.

The other thing to consider is instanceof is idiomatic code. It is
nearly always what you intend. Will your code break if someone
implements a subclass?

If you really mean ==, there is a high probability you are violating
oo-think and doing things procedurally as you would in C with Java
trappings.
 
R

Roedy Green

Got it!
Thanks Roedy,
by the way.... how did that homework of yours go?! did you receive anything
by DHL the next day?!!!

I wonder if anyone recognised himself in my parody. If so, it worked.

I discovered harping on writing good code is not nearly as effective
as lampooning bad code. See http://mindprod.com/jgloss/unmain.html

There are about 600,000 visitors to that page, more than any other.
 
W

Will Hartung

Thanks Will.
The code you provided was very helpful making me understand the difference.
now i can make my decision based on that.
this comparison is going to be used at a very low lever where it will be
repeated a huge number of times, and such a difference in bahavior will make
a difference in the performace of the application.

i definately need the direct class comparison using the == operator.

I'm glad I could help, but note the quoted bit I left in.

If you downcast a variable, you will be incurring the same cost as the
instanceof operator, simply because the run time system HAS to essentially
do the same thing (which is why you get an exception during the casting
operation, rather than when trying to act upon a casted object, like in
Smalltalk).

Now arguably:

if (o instanceof SomeClass) {
SomeClass x = (SomeClass)o;
....
}

is "slower" than:

if (o.getClass() == SomeClass.class) {
SomeClass x = (SomeClass)o;
....
}

But if you are SO concerned with the price of the instanceof test, I would
suggest you forego the classes entirely and work with some scary static
structure that never has a class cast or test anywhere near your main inner
loop.

You can try:
Method someClassMethod = getMethodFromSomeClass();
Object emptyParamList = new Object[0];
if (o.getClass() == SomeClass.class) {
someClassMethod.invoke(o, emptyParamList);
}

That will save you the cast, at the expense of building the parameterlist.
But then you may lose any benefit that the HotSpot JIT may give direct
method calls.

The point being that there are a lot of hidden costs in Java, and if you're
worried about something like instanceof, and feel that it stands out for
optimization, I think you're going to find a LOT of places that also incur
costs.

And, of course, you're going to benchmark this to see what really matters.

Regards,

Will Hartung
([email protected])
 
S

Stefan Ram

hilz said:
if so, then does one of them perform better that the other?
I kind of remember reading somewhere that "instanceof" has some overhead,
which makes it slower that the other option.

The result of "instanceof" might be cached at compile time
like this, because the classes needed to be tested after
"instanceof" are known at compile time, so there is only a
known finite set of them, which leads to this interface:

interface InstanceTestable
{
boolean instanceOfAlpha();
boolean instanceOfBeta();
boolean instanceOfGamma();
boolean instanceOfDelta();
boolean instanceOfEpsilon(); }

class Alpha extends Beta implement InstanceTestable
{
/* ... */
boolean instanceOfAlpha(){ return true; }
boolean instanceOfBeta(){ return true; }
boolean instanceOfGamma(){ return true; }
boolean instanceOfDelta(){ return true; }
boolean instanceOfEpsilon() { return false; }}

Then use this like, e.g.,

void example( final InstanceTestable o )
{ /* ... */
if( o.instanceOfGamma() )
{ /* ... */ }}

Now, when the JVM searches for "instanceOfGamma" it should
find it immediatly in the concrete class (assuming the object
"o" had class "Alpha"), while Gamma might be a very distant
indirect superclass of the class "Alpha".
 
X

xarax

Roedy Green said:
On the other paw instanceof is a single JVM instruction, and may be
highly optimised or short circuited via optimisation versioning. But,
in theory it SHOULD take longer than a single class compare.

As always MEASURE if it matters.

As discussed at length a long time ago in a galaxy
far far away, the instanceof operator can be implemented
to run to constant time regardless of the complexity of
the inheritance graph. Same goes for downcasting which
is a variant of instanceof. AFAIK, the Sun JVM does not
implement constant-time instanceof, but ISTR that the
GNU JVM does (but don't quote me on that -- eek!).

If it were my code, I would use instanceof, rather
than comparing Class objects for equality, simply
because it's easier to read and to grasp the intent.

2 cents worth. Your mileage may vary.
 
M

Michael Borgwardt

Roedy said:
I wonder if anyone recognised himself in my parody. If so, it worked.

I discovered harping on writing good code is not nearly as effective
as lampooning bad code. See http://mindprod.com/jgloss/unmain.html

There are about 600,000 visitors to that page, more than any other.

No surprise. A parody is entertaining, good advice is not. But it's
questionable if one rellay benefits from both equally.
 
W

Will Hartung

xarax said:
As discussed at length a long time ago in a galaxy
far far away, the instanceof operator can be implemented
to run to constant time regardless of the complexity of
the inheritance graph. Same goes for downcasting which
is a variant of instanceof. AFAIK, the Sun JVM does not
implement constant-time instanceof, but ISTR that the
GNU JVM does (but don't quote me on that -- eek!).

Really? Any memories as to how it could be made in constant time? Even a
hash table isn't constant time, unless it's a perfect hash table.

You could cache the lookup at the first hit, but for a majority of class
hierarchies, I'd question whether the hash table calc is any faster than
simply looking up couple of classes in a hierarchy. Certainly if your class
tree is 100 classes deep, and you're checking at the extreme ends, caching
would make sense. But most programs don't have class hierarchies that deep.
But then of course you have locality issues and CPU memory cache details,
and such.

I'm still curious how it could be in constant time. Whatever needs to be
done would have to be done at classload (as it can't be done at compile --
the total class hierarchy can change without needing to recompile).

None of this is really relevant to the question, of course.

Regards,

Will Hartung
([email protected])
 
Joined
Oct 26, 2008
Messages
1
Reaction score
0
I tried yaml, and it required a test of the kind of objects coming in.
When I moved the (x instanceof String) from the realtime loop
to the one-time yaml read-in loop, it speeded up from 42 seconds
to 1.4 seconds, but changing (x instanceof String) to
(x.getClass().equals(String.class)) left it at approximately
1.4 seconds to draw the same giant spreadsheet web page.

Thus, some combination of instanceof and converting
an object to String takes a large amount of time, and
that on a type like String that is a final class with no
subtypes in tree.

It would be better to have a yml option to read everything
in a String without having to convert it,
for applications that want to replace Java Properties
files with yml files.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top