views:

274

answers:

6

Hi all,

I am considering whether it is better to have two pointers, one for each object sub class and super, or whether I should just use casting.

How much system resources does this use:

objectName.functionOne();
((SubClass) objectName).functionOther();

Is it better than:

SuperClass objectA = (SuperClass) getSameInstance();
SubClass objectB = getSameInstance();
objectA.functionOne();
objectB.functionOther();

Basically, my main question is about the resources used with casting, versus making an extra pointer. It seems like I could save several in line casts, such as:

((SubClass) objectName).functionOther();

However, is it worth it?

Thanks,
Grae

UPDATE:

There were some unclear parts to my question. Basically, I have a super class that I am using through out a large function. It works with three subclasses. Some the super class is working as I would like. However, I hit a road block in a few places where I have to use a function from one of the three different subclass; a function that is only in one of the subclasses.

I could just have:

SuperClass instanceRef;
SubClass instanceRef2;

instanceRef.etc()
instanceRef.etc2()
instanceRef.etc3()
instanceRef2.specialSubClassOnlyCall();
instanceRef2.specialSubClassOnlyCall2();

or I could have:

SuperClass instanceRef;

instanceRef.etc()
instanceRef.etc2()
instanceRef.etc3()
((SpecialSubClass)instanceRef).specialSubClassOnlyCall();
((SpecialSubClass)instanceRef).specialSubClassOnlyCall2();

However, I don't know which is more efficient.

UPDATE 2:

Here is an example to show you what I am talking about:

class Shape
Triangle extends Shape
Square extends Shape
Circle extends Shape
Cube extends Shape

The Two Pointer Example: (Downside an extra pointer.)

Shape pointer1 = (Shape) getSomeRandomShape();
Cube pointer2 = null;

pointer1.getWidth();
pointer1.getHeight();
pointer1.generalShapeProp();
pointer1.generalShapeProp2();
pointer1.generalShapeProp3();

if(sure_its_cube)
{
   pointer2 = (Cube) pointer1;
   pointer2.getZAxis();
   pointer2.getOtherCubeOnlyThing();
   pointer2.getOtherCubeOnlyThing2();
   pointer2.getOtherCubeOnlyThing3();
   pointer2.getOtherCubeOnlyThing4();
}

Or I could do it this way. (Downside a bunch of casts.)

Shape pointer1 = (Shape) getSomeRandomShape();

pointer1.getWidth();
pointer1.getHeight();
pointer1.generalShapeProp();
pointer1.generalShapeProp2();
pointer1.generalShapeProp3();

if(sure_its_cube)
{
   ((Cube)pointer1).getZAxis();
   ((Cube)pointer1).getOtherCubeOnlyThing();
   ((Cube)pointer1).getOtherCubeOnlyThing2();
   ((Cube)pointer1).getOtherCubeOnlyThing3();
   ((Cube)pointer1).getOtherCubeOnlyThing4();
}

So is five casts worse than one extra pointer? What is it was six casts, or 20? Is one cast worse than the pointer.

Grae

+21  A: 

Do whatever makes the code clearer, forget about micro-optimizations.

Michael Borgwardt
It just seems like I should know how much resources a downcast uses, before I replace it with the allocation of another pointer. I get your point about it being small, but it just seems like I should know what I am doing. It is just like O-big for me. Suppose I have 10 downcasts, is that worth than one extra pointer?
Grae
@Grae - This advice isn't about "I should know what I am doing" its about "someone else should understand what you did"
Ivan
@Grae: What you should do is *stop even thinking about it!* Seriously, this kind of thing is a complete waste of brain time that would be much better used to make the code correct and easy to understand.
Michael Borgwardt
+1  A: 

Just go with whichever solution is easier to read and cleanest to maintain (likely the first solution). At that low a level of optimization, it's really not worth it except in edge cases where you really need the extra 0.01% performance improvement.

For what it's worth, you don't actually need to cast a subclass to a superclass reference (second solution listed), only the other way around. When casting a superclass to a subclass, it's generally preferred verify its type with instanceof prior to the cast rather than making assumptions.

Ophidian
+3  A: 

Casting is not an "operation" that is done at runtime. It's just needed by the compiler to assure you static type safety.

Just looked at JVM code, the two approaches are basically equivalent, they are implemented as

CHECKCAST Main$B
INVOKEVIRTUAL Main$B.mySubMethod()V

so a small overhead is present, but it's the same in both cases (since you gotta do a downcast anyway).

Jack
Casting may result in a runtime type check, which does include some (admittedly small) runtime cost.
mikera
-1, it is done at runtime (if the operation is not erased by the compiler). How do you think you get a `ClassCastException`?
Mark Peters
yes, but it is done in the same exact way in both situations!
Jack
That doesn't change the fact that it does happen at runtime.
Mark Peters
I was fixing my answer indeed :)
Jack
I'm too used to type inference lately, sorry for my initial mistake :(
Jack
I guess I could avoid having to do the down cast several times by having the extra pointer. That way I do the downcast once rather than for each time I use a subclass function.
Grae
+11  A: 
Péter Török
+1 - in my view this is the best answer, you should only need the SubClass pointer, inheritance takes care of the rest
mikera
getSameInstance would be getting the subclass, not the super class.
Grae
@Grae, nice, then my suggestion above works and you need no casts indeed.
Péter Török
There is however more than one type of subclass.
Grae
@Grae, now this is getting confusing. Note that the static type of the object returned may be different from its dynamic type. E.g. a method may be declared as `Object getSomeObject()` and may return a `String`, whereas the static type of the returned object is `Object`, the dynamic is `String`. I was referring to the static type the whole time - are you talking about the dynamic type? Or do you mean that `SubClass` has further subclasses? Please post the exact signature of `getSameInstance()` to clarify.
Péter Török
The part I think you are missing, is that there is more than one subclass. I am going to add something more to the question.
Grae
@Grae, see my update.
Péter Török
+2  A: 

Readability and code maintenance should be your priority in something like this, not performance, unless you actually hit a bottleneck (extremely unlikely).

However, there is no reason to have two references (pointers). Just reference the subclass. Anything you could do with the superclass reference you can do with the subclass reference, in almost all cases (a parameter to an overloaded method is the only exception I know of).

Yishai
@Yishai: in cases of method overloading you can cast the parameter to the parent type for free anyway. The static link is changed but the cast is thrown away, as is any up-cast that is statically known to succeed.
Mark Peters
A: 

Lets say you have a 64-bit machine and it saves 8-bytes of resources. Lets say you have spent 10 minutes think about it. Was it a good use of your time?

1 GB adds about $100 to the cost of a server so 8 bytes cost about $0.0000008

10 minutes of you time is worth about $1 on minimum wage.

The resource is reusable, your time is not. More importantly the time of anyone reading/ supporting your code is likely to be even more expensive and that is why simplicity/clarity is far more important.

Peter Lawrey