Java-Gaming.org Hi !
Featured games (90)
games approved by the League of Dukes
Games in Showcase (754)
Games in Android Showcase (229)
games submitted by our members
Games in WIP (842)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Check for null or check for implementation?  (Read 9607 times)
0 Members and 1 Guest are viewing this topic.
Offline Gibbo3771

JGO Kernel


Medals: 128
Projects: 5
Exp: 1 year


Currently inactive on forums :(


« Posted 2014-09-13 15:08:10 »

So I am curious, say I have this situation:

I have a base Entity class, it is not specialized in anything and only has a few members, once of them being a sprite.

So say I have a Player class that extends from this but the Player also implements an interface called Drawable.

I put a bunch of entities into an array, only the player implements this.

Is it faster to just do this:

1  
2  
if(sprite != null)
   entity.draw(batch)


Or is it better to check for implementation like so:

1  
2  
3  
4  
   if(entity.getClass().isAssignableFrom(Drawable.class)){
            Drawable drawable = (Drawable) entity;
            drawable.draw(batch);
         }


Although this is an example, and has quite a few flaws (why would a base class have a sprite if it is not specialized etc) but it is mainly a quick scenario I could think of.

What would be the logical one to do? Which would be faster?

"This code works flawlessly first time and exactly how I wanted it"
Said no programmer ever
Offline BurntPizza

« JGO Bitwise Duke »


Medals: 485
Exp: 7 years



« Reply #1 - Posted 2014-09-13 15:10:24 »

Null checks are very fast, reflection is generally slow.
Source, under "Low level safety checks": https://wikis.oracle.com/display/HotSpotInternals/PerformanceTechniques
Offline Gibbo3771

JGO Kernel


Medals: 128
Projects: 5
Exp: 1 year


Currently inactive on forums :(


« Reply #2 - Posted 2014-09-13 15:18:38 »

Null checks are very fast, reflection is generally slow.
Source, under "Low level safety checks": https://wikis.oracle.com/display/HotSpotInternals/PerformanceTechniques

Thanks for the link!

It is something I have never though of before, good to know at least. Not that I have any practical use for it at the moment but never know down the line.

"This code works flawlessly first time and exactly how I wanted it"
Said no programmer ever
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline nsigma
« Reply #3 - Posted 2014-09-13 16:21:19 »

Null checks are very fast, reflection is generally slow.

Not sure that counts as reflection, but anyway not sure why the OP's second example isn't

1  
if (entity instanceof Drawable) 


And even then it's the wrong way around

1  
if ( Drawable.class.isAssignableFrom(entity.getClass()) )


And be wary of either - have an overridden method in your entity if possible, even if that's a no-op.

Praxis LIVE - hybrid visual IDE for (live) creative coding
Offline basil_

« JGO Bitwise Duke »


Medals: 418
Exp: 13 years



« Reply #4 - Posted 2014-09-13 17:29:11 »

Quote
Class.isInstance and Class.isAssignableFrom are as cheap as instanceof bytecodes when the operands are constants, and otherwise no more expensive than aastore type checks.

doesn't tell if its client or server or both. but usually server performs better.
Offline richierich
« Reply #5 - Posted 2014-09-13 18:10:07 »

What would be the logical one to do?

First review your program design - the need to cast or use instanceof is often a warning the design could be cleaner. I've many times cast when coding in a hurry and then proceeded to run into stickier and sticker waters only to finally realise the problems were coming from the issue I ducked with the cast to start with Smiley Obviously it's sometimes OK, especially if you're modifying an existing program where you don't really have the option to redesign everything, but still have a think anyway.

But to answer the question I usually put a function in the base class like boolean isDrawableInMainEntityLoop() or whatever. It's clear but kind of deliberately clunky as a reminder there's a potential hack there.
Offline nsigma
« Reply #6 - Posted 2014-09-14 09:33:30 »

Quote
Class.isInstance and Class.isAssignableFrom are as cheap as instanceof bytecodes when the operands are constants,

Note the emphasis though!  Wink

First review your program design - the need to cast or use instanceof is often a warning the design could be cleaner. ... I usually put a function in the base class like boolean isDrawableInMainEntityLoop() or whatever.

So you replace a wart with a tumour?  Grin  IMO people sometimes try too hard to remove instanceof and replace it with something many times more complicated or worse performing.  I think it has its place, particularly considering Java lacks double dispatch.  I think using it to search for objects with a certain capability (ie. implements Drawable) is OK, as long as you're only looking for a single capability at a time - if you have a chain of 'if instanceof else if instanceof' then you do have a problem.

Praxis LIVE - hybrid visual IDE for (live) creative coding
Offline Roquen

JGO Kernel


Medals: 517



« Reply #7 - Posted 2014-09-14 14:02:34 »

instanceof has a rather large stink factor.  If you need one then you should think if there's a design flaw.  That's quite different from saying you should never use one...and if you do then jumping through hoops to avoid it probably isn't the solution.

Quote
I put a bunch of entities into an array, only the player implements this.
If the original question was important...then the answer is in that statement.

Quote
if(sprite != null) entity.draw(batch);
This is a very odd construction.  Checking if sprite is null and then not directly doing anything with sprite.  From the previous it looks like everything is burdened with 'sprite' and only the player will have non-null value.  If so then 'sprite' is useless.
Offline cylab

JGO Kernel


Medals: 180



« Reply #8 - Posted 2014-09-14 18:01:21 »

I actually like instanceof, especially when designing object hierarchies. I never got why so many people try to work around it. It's quite straight forward and easy to just ask an object what it is to decide what to do with it. Why would you not want to use such an important attribute of an object like it's type?

Having said that, the OPs problem is easy to solve by just calling
entity.draw(batch)
on any type of entity and implement the
draw(batch)
empty for entities not having a sprite... I doubt that using the null-check to prevent calling an empty method will boost performance significantly for any kind of game we are doing here.

I would do it different though (using instanceof). Something along the lines of:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
class World
{
    List<Entity> entities=new ArrayList<Entity>();
    List<Drawable> drawables=new ArrayList<Drawable>();

    add(Entity e) {
        entities.add(e);
        if(e instanceof Drawable)
            drawables.add((Drawable)e);
    }

    draw(Batch batch){
        int l=drawables.size();
        for(int i; i < l; i++)
            drawables.get(i).draw(batch);
    }
}


You can do this kind of specialized "caches" with all kind of "filters" that create more or less static lists of objects you need to iterate over and handle type (or otherwise) specific. The only downsides are slightly increased memory foodprint (multiple references to the same object) and some performance overhead for adding and removing objects to/from multiple lists.

I really can't see, why this kind of desing is bad practice, inperformant or "stinks".  

Mathias - I Know What [you] Did Last Summer!
Offline Roquen

JGO Kernel


Medals: 517



« Reply #9 - Posted 2014-09-15 07:24:45 »

Let's ignore performance tuning.  Cylab's example is reasonable enough, although I'd think about only placing each in one list instead in both...but without further knowledge I can't really say.  But it's somewhat moot for OP's question:  "... only the player implements ..."

Generally using instanceof is an explicit type query which in general requires walking lists and requires selecting the exactly right type.  And the situation is worse if the type is an interface type.  Choose the exactly right type can be problematic if you rework the type hierarchy and all relevant instanceof checks will require change.  So instead of an explicit type query, replace it with an implicit via an instance method/variable.  Remember that this is all general speak.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline cylab

JGO Kernel


Medals: 180



« Reply #10 - Posted 2014-09-15 07:50:18 »

It's in both lists because Entity would be the most generic type in this example and Drawable is a subset. So if you want to do something with all entities you would iterate only the entities list. This makes more sense, if you have more subsets, especially if they might overlap partly, so you can't just iterate over all lists to so something with all entities once.

Mathias - I Know What [you] Did Last Summer!
Offline Rayvolution

« JGO Spiffy Duke »


Medals: 379
Projects: 2
Exp: 2 years


Resident Crazyman


« Reply #11 - Posted 2014-09-15 08:04:05 »

I do null checks quite often now, I know it's a coding faux pas, but damn it. It makes sense in a lot of cases. Wink

For example, when a villager dies in RPC, part of the death() method does this:

1  
2  
3  
4  
5  
if (mate != null){
   mate.decreaseHappiness(75);
   mate.removeMate();
   removeMate();
}


Basically, it checks if it has a mate, if it does, removes the "bond" between the two, so the survivor can find a new mate in the future.

I believe the technically correct answer is "you shouldn't do it" though. But hey, I like it.


- Raymond "Rayvolution" Doerr.
Retro-Pixel Castles - Now on Steam!
LIVE-STREAMING DEVELOPMENT: http://www.hitbox.tv/rayvolution
Offline princec

« JGO Spiffy Duke »


Medals: 1029
Projects: 3
Exp: 20 years


Eh? Who? What? ... Me?


« Reply #12 - Posted 2014-09-15 08:08:25 »

Make OOP purists recoil in horror with the suggestion that you stick loads of methods into a base class! That's what I do.

In general I look back from the requirements ("I need to be able to this, this, and this, with the things in a list") and then work out what thing needs to be done to satisfy those requirements ("so I need to have this, this, and this declared for all potential objects in the list"). Quite often that leads to the perfectly reasonable design of having a phat base class full of abstract methods (or, more usefully, an interface).

Then I move on to more actually difficult problems Wink

Cas Smiley

Offline Roquen

JGO Kernel


Medals: 517



« Reply #13 - Posted 2014-09-15 08:18:13 »

@cylab: Like I said...it depends what I'd do.  If partitioned into different sets then you just iterate over the set of sets that each transform needs to work with, then nothing needs to check if the transform applies to that specific instatance.

@Rayvolution: that's a statistically insignificant example...doing whatever works best for your brain is the right approach.

Quote
Then I move on to more actually difficult problems
This.
Offline Rayvolution

« JGO Spiffy Duke »


Medals: 379
Projects: 2
Exp: 2 years


Resident Crazyman


« Reply #14 - Posted 2014-09-15 08:19:29 »

@Rayvolution: that's a statistically insignificant example...doing whatever works best for your brain is the right approach.

This should be the answer to all programming questions. Wink

- Raymond "Rayvolution" Doerr.
Retro-Pixel Castles - Now on Steam!
LIVE-STREAMING DEVELOPMENT: http://www.hitbox.tv/rayvolution
Offline nsigma
« Reply #15 - Posted 2014-09-15 08:20:54 »

Generally using instanceof is an explicit type query which in general requires walking lists and requires selecting the exactly right type.  And the situation is worse if the type is an interface type.

Huh? Why? IMO, using with interfaces makes the most sense as it's effectively using instanceof as has-capability-to.

Quite often that leads to the perfectly reasonable design of having a phat base class full of abstract methods (or, more usefully, an interface).

That depends.  Having no-op methods isn't too bad, but take something like the List interface - having an API where half the methods are defined to throw exceptions when they're not supported is IMO even more daft than having a sub-interface and using instanceof to check if it supports modification.

Then I move on to more actually difficult problems Wink

+1  Grin

Praxis LIVE - hybrid visual IDE for (live) creative coding
Offline Roquen

JGO Kernel


Medals: 517



« Reply #16 - Posted 2014-09-15 08:42:37 »

Quote
Huh? Why? IMO, using with interfaces ...

Short answer.  Classes only have a single parent and interfaces are a potentially arbitrary list per class, so in general more searching is required in the interface case.  And yes both cases include possibilities of optimization.
Offline nsigma
« Reply #17 - Posted 2014-09-15 09:16:05 »

Short answer.  Classes only have a single parent and interfaces are a potentially arbitrary list per class, so in general more searching is required in the interface case.

None answer??  Tongue  I'm not sure where the list is relevant, unless we're talking about the actual bytecode required (which I didn't think you were?)

Choose the exactly right type can be problematic if you rework the type hierarchy and all relevant instanceof checks will require change.

This is where an interface would seem to make more sense, not less.  If you treat the interface as a capability you're filtering for, you can change your type hierarchy and implementation as much as you want - a good reason to choose an interface over a concrete type, no?

I'm not advocating it as a general approach, but it does make sense occasionally, particularly when (as per previous post) the alternative involves methods throwing exceptions.

Another alternative I like, though not going to perform quite as well, is something like the Lookup.Provider API in the NetBeans platform where you make the entity responsible for providing its own capabilities - something like

1  
2  
3  
4  
Drawable d = entity.getLookup().lookup(Drawable.class);
if (d != null) {
  d.draw();
}

Praxis LIVE - hybrid visual IDE for (live) creative coding
Offline ClaasJG

JGO Coder


Medals: 42



« Reply #18 - Posted 2014-09-15 09:26:09 »

http://en.wikipedia.org/wiki/Entity_component_system

There a nice libs out there even for java.
Because I see Interfaces used as components right here in this thread Cheesy

-ClaasJG

My english has to be tweaked. Please show me my mistakes.
Offline cylab

JGO Kernel


Medals: 180



« Reply #19 - Posted 2014-09-15 10:40:42 »

Because I see Interfaces used as components right here in this thread Cheesy
Actually it's the oposite way around. Entity systems use components as replacement for interfaces Tongue

Mathias - I Know What [you] Did Last Summer!
Offline Roquen

JGO Kernel


Medals: 517



« Reply #20 - Posted 2014-09-15 11:08:41 »

Short answer.  Classes only have a single parent and interfaces are a potentially arbitrary list per class, so in general more searching is required in the interface case.
None answer??  I'm not sure where the list is relevant...
I'm referring to the code with which must execute to return true/false.
Offline Cero
« Reply #21 - Posted 2014-09-15 13:36:05 »

I dislike instanceof too, I never use it eventually.

It always seems to me that code like that wants to be as general as possible, cover all the cases but then cop out and do this

Especially in game programming

Pages: [1]
  ignore  |  Print  
 
 

 
DesertCoockie (20 views)
2018-05-13 18:23:11

nelsongames (68 views)
2018-04-24 18:15:36

nelsongames (65 views)
2018-04-24 18:14:32

ivj94 (748 views)
2018-03-24 14:47:39

ivj94 (79 views)
2018-03-24 14:46:31

ivj94 (555 views)
2018-03-24 14:43:53

Solater (94 views)
2018-03-17 05:04:08

nelsongames (168 views)
2018-03-05 17:56:34

Gornova (338 views)
2018-03-02 22:15:33

buddyBro (998 views)
2018-02-28 16:59:18
Java Gaming Resources
by philfrei
2017-12-05 19:38:37

Java Gaming Resources
by philfrei
2017-12-05 19:37:39

Java Gaming Resources
by philfrei
2017-12-05 19:36:10

Java Gaming Resources
by philfrei
2017-12-05 19:33:10

List of Learning Resources
by elect
2017-03-13 14:05:44

List of Learning Resources
by elect
2017-03-13 14:04:45

SF/X Libraries
by philfrei
2017-03-02 08:45:19

SF/X Libraries
by philfrei
2017-03-02 08:44:05
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!