Alternatives for instanceof

Hi all,
It has come to my attention from some developers that instanceof is slow. And that seems to be the bottleneck to my AI routines. So I was wondering on an alternative to instanceof?

Thx a million, DP

You can always use an interface like this:


public interface AIObject
{
    public int NEURON = 1;
    public int PULSE = 2;
    public int DECISION = 3;

    public int getObjectType();
}

Simply implement the above interface for each of your custom objects, then call “getObjectType()” to find out which object it is.

Gotcha, plus/minus a few changes and im there. Thx jbanes

As for the speed of instanceof - it depends. It does not have to be slow - for classes, it is perfectly possible to be 2/3 assembler instructions. For interfaces it can be harder.

I suppose that what is killing you is not instanceof itself, but conditional branches (if/else tree). Mispredicted jump is very costly on most architectures. JBanes solution helps here, as you can use tableswitch then, which takes just a single jump (althrough costly).

Anyway, I have heard at some point in the past than casting and instanceof are signs of non-OO programming and I kind of believe it. Of course, it is just a general guide - same as goto can be useful in lexer/parser generation, sometimes instanceof/cast can be best solution. I do not count pre-1.5 collections here, or equals(Object) method - these are java language deficiencies. But if you see method like


class Animal
{
    public void eat(Fruit f) {
        if ( f instanceof Apple ) {
        } else if ( f instanceof Orange) {
        } else if ( f instanceof Peach ) {
        } else ...         
    }
}

you know something is wrong…

Can you tell us more about a case where you need instanceof ? Maybe it can be solved other way ?

P.S.
Multimethods (runtime polymorphism depending on the argument type past ‘this’) would be cool…

Yeah, if you have all the language-level support for doing full OOP, then you shouldn’t see instanceof. Sadly, we’re not yet there with full OOP support in java :frowning: particularly in it’s various polymorphic deficiencies (pre-1.5 it only has basic polymorphism). This is a big problem with writing 3rd-party library code, especially user-extensible library code (where what you really want is probably C++ templates + some extras ;)), where full polymorphism can increase your readability, extensibility, maintainability by a huge leap (if you know what you’re doing…).

it is much like the animal eats fruit criteria. However, I know that there will only ever be 2 types of fruit the animal could eat. Either Apple or Orange.

Putting this in a more concrete example, I have:

-AbstractEntity
-Entity extends AbstractEntity
-EntityNode extends AbstractEntity

When I need to pass messages from one entity to another using MessageRouter, I need to know if im passing down to a node or an entity. If its a node, then pass the message down to all its children. If its an Entity then pass it the message.

There will only ever be Entity and EntityNode, so no complicated if else conditional statements.

On a side note, instanceof seemed not to be my bottleneck, infact, it was faster than calling the getType() method !

As many wise men said: Premature optimisation is the root of all evil. And that is what I was doing, premature optimisation.

DP

Does the message router really need to know this? Or should there be a method called ‘receiveMessage()’ on an Entity and a EntityNode such that for an Entity, the message will be handled by itself, while the EntityNode will forward the message to all of it’s contained Entitys. Seems to me that the OO aspect of implementation hiding would come very handy here.

-Chris

MessageRouter has the root EntityNode as an argument. You call the sendMessage on the Router and it will monitor when the message should be sent. Because the message could have a delay.

And yes, Entity does have recieveMessage(Message m) in it because that is what will be sent. The Router does exactly what says on the tin. It routes messages from one entity to another.

DP

I explained how to do this in a diary entry for XAP last year some time but more or less you can do this entirely by using the following pattern:


public interface Eater {
      public void eat(Fruit fruit);
      public void eatApple(Apple apple);
      public void eatOrange(Orange orange);
      public void eatBanana(Banana banana);
}

public interface Fruit {
      public void eatenBy(Eater eater);
}

public abstract class Animal implements Eater {
      public final void eat(Fruit fruit) {
            fruit.eatenBy(this);
      }
      
      public void eatApple(Apple apple) {
            System.out.println("Burp");
      }
      public void eatOrange(Orange orange) {
            System.out.println("Yum");
      }
      public void eatBanana(Banana banana) {
            System.out.println("Yuk!");
      }
      
}

public class Monkey extends Animal {
      public void eatBanana(Banana banana) {
            System.out.println("Monkey likes bananas!");
      }
}

public class Apple implements Fruit {
      public void eatenBy(Eater eater) {
            eater.eatApple(this);
      }
}

public class Orange implements Fruit {
      public void eatenBy(Eater eater) {
            eater.eatOrange(this);
      }
}

public class Banana implements Fruit {
      public void eatenBy(Eater eater) {
            eater.eatBanana(this);
      }
}

and unless Java’s JVM team have been telling us porkies that should optimize very nicely indeed, and it’s very easy to extend and provide fine-grained behaviour.

Cas :slight_smile:

class Applet
{
   public void eat();
}

think OO 8) Question whats wrong with the Apple ? ::slight_smile:

Apple does “eat”. Though it does it through the tree. The tree’s roots absorb moisture in the soil.

Applet is supposed to be Apple, right?

Most of the multiplayer games I’ve written have used instanceof fairly heavily. The network layer I wrote allows sending any Object over the network to the server. When the server or a client receives an Object, I use instanceof to handle the object appropriatly. For example:


public void objectReceived(Object o)
{
   if(o instanceof Ping)
          handlePing(o);
   else if(o instanceof GameState)
          handleGameState(o);
   else
         .... ....
}

Is this poor practice? Should whoever’s using the network layer only have one object that is sent around, so you always know what type it is?

There are few other solutions.
a) Use packet type id in switch statement.
b) Add message-handling code to packet class itself - even if it is just calling handler.handle(this) to get static dispatch working (like Cas example)
c) use some kind of RMI instead of dispatching method to data manually

Use precisely the method I outlined in that code snippet.

Cas :slight_smile:

That the Visitor pattern isnt it?

Might be. They started giving names to things we’d all been doing for years not so long ago. Us old farts can’t keep up.

Cas :slight_smile:

It is the visitor pattern… and the pattern has been around for like 20 years… so you must be reeealy old :wink:

31 and a half :wink: Been programming since 7 or so though.

Good grief.

Cas :slight_smile:

So what would you do if your Fruit types were dynamic? Suppose a run-time plugin added Grape, which the Monkey wasn’t designed to receive. Grape would somehow have to determine that the target animal does/doesn’t have an eatGrape() function. You’d end up with something like “is Monkey instanceof GrapeEater”, and then each animal implements a set of xxEater interfaces.

It’s a shame that polymorphism doesn’t automatically do this for us… that is, if the object is of type Grape, then it could automatically call .eat(Grape g) instead of .eat(Fruit f). Just pick the most specific type and work your way up until you find a matching function.

Our system has both run-time dynamic plugin message generators and run-time dynamic plugin message receivers. We use a type combined with the source of the message; that is,

if (obj.Source == FruitTree && obj.type == FruitTree.APPLE)
eatApple((Apple)obj);

mostly because we didn’t want to try to define a unique ID to each type of message (ie, didn’t want to create a global message ID namespace). So our message types are only unique within their own source, and we check both.

However, this is little more than a fancy instanceof, and I’m curious what the “proper” solution is supposed to be.

Solution is to use object with real support for OO instead of java…

Jokes aside, I don’t think that this problem can be solved in generic case. If you have truly dynamic system, with two independent libraries extending base objects, there is no place to put definition of what should happen when these two subclasses will meet. You need to provide some kind of methods which will describe an object in a way which could be changes by just overriding base object methods.

When I think about multimethods, standard method call notation stops to make sense. What is needed is just a possibility to write
method(ClassA a, ClassB b)
and have it to work on dynamic type of arguments (so you will call method(a,b) instead of a.method(b));
Second thing needed is ability to define such methods out of scope of any class - and I end up with Nice (http://nice.sourceforge.net/index.html). Anything short of that is just a hack.