Archived

This topic is now archived and is closed to further replies.

fractionMan

[java] The cost of casting

Recommended Posts

My current project has to cast things, and quite often. I have to cast when I put things into an arraylist and when I take them out. I also have to cast things after the''ve been passed as parameters. How expensive (in terms of time) is this? What alternatives are there? (I suppose I could implement my own arraylist)

Share this post


Link to post
Share on other sites
Hmm, i can''t tell you in terms of time, but there is some cost, mainly because all casts in Java are made at run-time. *Maybe* you could avoid this expense if you''d use Generics (it''s like the C++ so-called ''templates''). But i think nobody uses generics in java yet (maybe in the future jdk-1.5).

The thing you must think of is: do you really need extreme performance? If not, then don''t worry about it. If yes, well, erm, maybe you can try some other language, such as C++. Or you can try making your own arraylist, yeah...

Victor.

Share this post


Link to post
Share on other sites
If your only working with a single type of object that would be returned, it would be a good idea to make a class of your own. I had to do this in one project of mine. It has more benifets than just eliminating the overhead of cast as you can eliminate some additional features (syncronized) of the standard classes.

Share this post


Link to post
Share on other sites
Hi,

The casting is IMO the last thing you should be concerned with regarding to speed. Excessive string concatenation, abuse of the reflection API, unnecessary object creation can be sources of much greater slowdowns than simple casting!

P.S.: The standard collection classes ARE NOT synchronized. In fact only the two legacy collection classes (Vector and Hashtable) are synchronized.
So if you are unable to switch to the new (they're pretty old actually -> since 1.2) collections - Lists (LinkedList, ArrayList), Sets (TreeSet, HashSet) and Maps (HashMap) - don't complain, that the old implementations are synchronized.

have fun

[edited by - Petr Stedry on March 18, 2003 11:28:28 AM]

Share this post


Link to post
Share on other sites
Judging by the above advice, I suppose that my Vector2D class was a bit of a bad move.
Nearly every method returns a new Vector2D, so I can things like:
v = vv.add(aVec).sub(aVec).unit();

unfortunately, I often just need:
vv = vv.add(aVec).sub(aVec).unit();

which would create three new vectors.

Well, you can see my XXX rated asteroids cloner that I'm working on at the mo. It's seems fast enough, and I haven't optimised anything yet.

[edited by - fractionMan on March 18, 2003 1:13:26 PM]

Share this post


Link to post
Share on other sites
Hi fractionMan,

if your "Vector2D" class consist of two primitive numbers only, you need not worry (IMO) about excessive object creation regarding to Vector2D. Of course if the slowdowns caused by the GC are noticable on the target system you'll have to optimize.

trial and error is a way to go ... sometimes

[edited by - Petr Stedry on March 19, 2003 7:57:44 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by fractionMan
Nearly every method returns a new Vector2D, so I can things like:
v = vv.add(aVec).sub(aVec).unit();

unfortunately, I often just need:
vv = vv.add(aVec).sub(aVec).unit();

which would create three new vectors.



That does not create three new vectors. And in fact, you should be able to just do this:


vv.add(aVec).sub(aVec).unit();


Give it a try, I think it''ll make things a bit easier for you :D

The only time you''re creating a new object is when you actually use the
new 
keyword.

Share this post


Link to post
Share on other sites
I presume, he uses "new" to create a new object in each of the methods (add,sub). I find this approach good, because it eliminates the possibility, that you link some object accidentally to somewhere, where it should not be as this can produce unexpected behaviour.

Share this post


Link to post
Share on other sites
-->markuskidd
Petr got it spot on,
In order to be able to stick two methods (or more) in a row, each method must return a Vector2D.
vv.add(aVec).sub(aVec).unit();
If add() returned a void, then the .sub() would have no meaning.
Example method:


public Vector2D add(Vector2D v){
return new Vector2D(x+v.x,y+v.y);
}


Which is what my code does. However, this is so useful I think it''s worth keeping.

On another note, I just found out that arrays of primitive data types are actually objects, so:
int [] x = {1,2,3,4};
int [] y = x;
// y now points to x.
I could understand it if it was Objects, but didn''t expect it with primitives. Took me a while to figure out what was going wring there.

Share this post


Link to post
Share on other sites
quote:
Original post by fractionMan
On another note, I just found out that arrays of primitive data types are actually objects, so:
int [] x = {1,2,3,4};
int [] y = x;
// y now points to x.



Of course arrays are objects... I mean, you can call wait, notify, notifyAll, clone, getClass on them (and others, but those are just ones I''ve used), synchronize on them, and access their public final length field.... I mean, none of that''d be possible if they weren''t objects.

Share this post


Link to post
Share on other sites
quote:
Original post by fractionMan
-->markuskidd
Petr got it spot on,
In order to be able to stick two methods (or more) in a row, each method must return a Vector2D.
vv.add(aVec).sub(aVec).unit();
If add() returned a void, then the .sub() would have no meaning.



lol, yeah :D i know

quote:

Example method:


public Vector2D add(Vector2D v){
return new Vector2D(x+v.x,y+v.y);
}


Which is what my code does. However, this is so useful I think it''s worth keeping.



I was thinking you had something (which is a lot more in line with getting performance out of Java) more like this:


public Vector2D add(Vector2D v) {
x += v.x;
y += v.y;
return this;
}


This is the paradigm a lot of people use (including the authors of java.nio). Object generation during your main game loop should be extremely rare outside of any networking you may be using.

quote:

On another note, I just found out that arrays of primitive data types are actually objects, so:
int [] x = {1,2,3,4};
int [] y = x;
// y now points to x.
I could understand it if it was Objects, but didn''t expect it with primitives. Took me a while to figure out what was going wring there.


As someone else mentioned, arrays aren''t primitives.

Share this post


Link to post
Share on other sites
Actually, any functions that, for instance, return a new Vector2D that is the sum of two other ones should be static to your Vector2D class or another utility class and should take both Vector2Ds as parameters.

Share this post


Link to post
Share on other sites
For some reason, it was lodged in my head that an array of objects is an object, but an array of primitives was a primitive type itself. Ho Hum.

quote:

public Vector2D add(Vector2D v) {
x += v.x;
y += v.y;
return this;
}


quote:

Actually, any functions that, for instance, return a new Vector2D that is the sum of two other ones should be static to your Vector2D class or another utility class and should take both Vector2Ds as parameters.



These ideas do make alot of sense. Maybe next time...

On yet anothjer related point, I need to implement some type of sound manager for my applet.
I was thinking of making a singleton that implements runnable and runs in it's own thread to load the sounds, and has static methods to allow the rest of the app to play sounds.
Is this a good idea?




My rather foulmouthed asteroids applet

[edited by - fractionMan on March 21, 2003 5:17:41 AM]

Share this post


Link to post
Share on other sites
I''d say the singleton design pattern is OK for a sound manager after all.

Just add another File manager, that handles the file loading for the sound manager to remain as modular as you can be.

That''s all folks ...

Share this post


Link to post
Share on other sites
quote:
Original post by fractionMan

On yet anothjer related point, I need to implement some type of sound manager for my applet.
I was thinking of making a singleton that implements runnable and runs in it''s own thread to load the sounds, and has static methods to allow the rest of the app to play sounds.
Is this a good idea?




Also, loading the sounds in a separate thread might be a bit of design overkill, though it''s hard to tell without seeing what you''re doing.

Since you''ll want to make sure you have the sounds loaded before the game starts, why not just block on I/O? This will ensure the sounds are loaded at a certain point, so you won''t have to add a lot of checks in your sound manager class for sounds that haven''t loaded.

/B

Share this post


Link to post
Share on other sites
I was thinking of loading in some simple sounds before the games starts, and loading in bigger sounds in the background while the game is in progress. This way, you can start quickly, but the sounds will improve after a few minutes. Whadda ya think?

Share this post


Link to post
Share on other sites
quote:
Original post by -vic-
Hmm, i can''t tell you in terms of time, but there is some cost, mainly because all casts in Java are made at run-time. *Maybe* you could avoid this expense if you''d use Generics (it''s like the C++ so-called ''templates'').


From what I have read about the implementation of generics in Java(not all that much, admittedly), generics wont help performance since they merely hide the runtime casts. This was reportedly a conscious design decisions to avoid having to modify the virtual machine in order to support generics. .NET will implement generics at the runtime level.



"If there is a God, he is a malign thug."
-- Mark Twain

Share this post


Link to post
Share on other sites
my rumor mill alludes that this may be the situation at the beginning, but that a more c++-style implementation will be around later

and, as always, .NET will always be sniffing around a few steps behind

Share this post


Link to post
Share on other sites
The current JVM does a clever optimisation trick with casting. Apart from being an incredibly cheap operation in the first place, it has some trick up its sleeve that makes the operation virtually free on subsequent casts on the same object to the same type.

I think.

It''s not relevant to game performance anyway.

Cas

Share this post


Link to post
Share on other sites
quote:
Original post by markuskidd
and, as always, .NET will always be sniffing around a few steps behind

Yeah, I guess that''s why Java is going to implement enums and value types now




"If there is a God, he is a malign thug."
-- Mark Twain

Share this post


Link to post
Share on other sites
quote:
Original post by Arild Fines
[quote]Original post by markuskidd
and, as always, .NET will always be sniffing around a few steps behind

Yeah, I guess that''s why Java is going to implement enums and value types now




"If there is a God, he is a malign thug."
-- Mark Twain


I can only imagine when they get their virtual machine up and running on more than just Win32. What a party that will be!

Share this post


Link to post
Share on other sites