ArrayList, Hashtable, or ... for holding in-game-objects

No, generally speaking, it creates almost no garbage at all. Unless you create 10,000 bullets every single frame. This does not happen :slight_smile:

Cas :slight_smile:

I think that depends on the size of your game.

In a smaller game an array is fine, but in a larger Project its not a good choice as it is potentially more error-prone
due to wrong use.

I use ArrayLists rather than arrays with current size var because… well, that’s what OOP was invented for. So you didn’t have to keep doing that sort of crap everywhere. The VM optimises it to the point where it won’t make a great deal of difference and as Damocles says, it’ll just lead to more errors, duplicated code, and yucky looking code.

Cas :slight_smile:

+1. Use arrays and you’ll slowly start writing your own ArrayList, and probably a suboptimal one at that! :slight_smile:

One possible performance improvement, inspired by @theagentd’s comment (or maybe exactly what he means?), would be a list that didn’t null everything on clear(), just resets the counter, and has a separate cleanup() method that nulls everything past the counter value. Obviously, you call cleanup() every now and again to GC, but if the size of the list remains fairly constant, that should only need to null a few references rather than iterating through everything on every frame.

And it’ll be a PITA to implement, and you’ll probably gain next to nothing! ;D

Okay then, these are all good points! I guess I haven’t worked on a sufficiently-sized project yet to encounter these problems. I’m open to the idea of doing this 1% less efficiënt to make it 10% less error prone ;D

Thanks for the advice, I’ll have a good long look at the other approaches described here.

Exactly what I meant. I claim that one! =S

The speed of clearing that list to null is incredibly fast. I mean, really, incredibly fast. Even if the list is really, really big. And who knows what benefits it will have on the garbage collector. Probably only positive ones. Premature optimisation ftw!

Cas :slight_smile:

What about just nulling out the elements that did not get overwritten after the last buffer migration? GC win plus less nulls. I might write a small class for this one day…

How about (as I pointed out earlier), nulling out the index when removing it, then removing all nulls after the loop ends?

Knock yourself out, but I’m with princec - I think it’s a lot of work for no gain. It’s probably not even premature optimisation - you might just be jumping straight to premature evil. :wink:

Isn’t your suggestion just premature deoptimization! :slight_smile: Aren’t you just forcing yourself to iterate an extra time, and doing more in the process?

I will go with double buffered ArrayList. I’m implementing that on my code right now. It works well so far. I’m gonna test around.

I learned several new things from this topic. Very interesting to hear others’ opinions. I have to look more into GC to understand better.

In my case, I believe double buffered ArrayList would be more efficient than Bag. Like I said above, I think keeping entities in spawned order is more appropriate. If I was to use Bag to hold entities, I would be looping backwards to enable removing and not missing any element while iterating. If I need a structure to hold static number of things, then I would just go with array or the most simple.

Thanks a lot guys.

May I ask someone to explain the purpose of the temp ArrayList in princec’s code example? Setting entities1 = temp right before you .clear() it seems unnecessary, though I’m sure there is a reason for doing so. Is this done to help java’s garbage collector?

Thank you,
-Bukky

The temp ArrayList is used so that you can switch the references of entities0 and entities1. Then you clear entities1 so you can re-add entities then next time the for loop is executed. It is true you could have just done “entities1 = new ArrayList()” but why waste memory? :wink:

Btw, welcome to JGO :slight_smile:

why can’t you just do this

entities0 = entities1;
entities1.clear();

wouldn’t that accomplish the same thing? what am I missing here? WHY AM I SO DUMB ??? :-\ :emo:

Thanks!

You’re probably mixing up references and instances. In this case we have two instances of ArrayList. We also have two references, each pointing to one of the ArrayList instances. With your code you’d set both references to point to the same instance, and one of the ArrayList instances will be forever unreachable and garbage collected. Picture yourself holding two apples (instances), one in each hand (reference). How do you switch apples between your hands? You can’t hold two apples in one hand, so you’ll have to put one apple down on a table (the temp ArrayList reference), then move the other apple to the first hand and finally pick up the first apple from the table with your other hand.

I may have just overcomplicated it a lot, but I hope you understand… xD

Also you gotta remember that a variable (of class types) only references the object.


entities0 = entities1;

Here, both entities0 and entities1 refer to the same object


entities1.clear();

This calls the clear() method of the object referenced by entities1, the same object referenced by entities0.

Before all this, entities0 and entities1 referred to 2 different objects and, as theagentd explained, we simply switched the references and cleared one.

No, that was a beauteous metaphor.

Thank you both theagentd and ra4king, I understand now!

Linked lists are the building blocks for structures like B* trees which are your basic database index structure.

That’s no different to any other language. C++ game developers don’t naively use every container in STL either, you know.

Could someone post the source code for that Bag collection? The link Appel supplied is broken.

Thx!