Removing an object from a table question

For 99.9% of uses pairs() is fast enough.

I had a situation once where an inner in-pairs loop over a small number (6) of known keys, but done many thousands of times (up to 50 matches, 18 times per match x 11 players x 18 attributes) was a bottleneck.

By storing the key names in a separate numerically indexed table and iterating over this in a for loop to access the keys directly, I shaved fractions of a millisecond per operation and halved overall processing time.

One question:

for what is the following part in the code:

function enemy.finalize(self) enemies[self] = nil end; enemy:addEventListener("finalize")

?

the real question is why are there “more than 1000 enemies” - that seems like an unrealistically large number on screen

suspect that’s the “entire population” for the “entire wave”, with some perhaps far offscreen, yet still participating in the collision test, likely with doubly nested loops over the entire population (so 1000*1000 tests - now THERE’s enough to notice a performance hit)

if instead you kept (and managed) a separate list of enemies “within the viewport” then life would be much simpler

and if you happened to have them in an indexed list than you could reduce the inner collision loop to a triangular array

in short:  you could optimize the list storage/retrieval all you want, but to no real practical effect if the problem is at a “higher level” (ie, if you can’t fix what i suspect is an O(n2) problem in the collision loops, then worrying about the performance of pairs() is moot)

[EDIT]  nah, it’s probably not quite that bad, as you don’t actually say you’re colliding enemy-vs-enemy.  so ignore the O(n2) and triangular array bits, but if you’re still colliding something like 100 bullets vs 1000 enemies, where maybe half or more of those enemies are offscreen, then the rest still applies – the fastest way to do something is to not do it.

Got it! Thanks for all your help!

I somewhere had a reference to objects, so they didn’t get cleared the right way, when being removed. I now have implemented the code RoamingGamer suggested (Thanks a LOT for this!) and will make the changes to the complete game in the next days. It now works fine regarding the memory and the system memory is now steady because when an enemy is getting destroyed or removed the memory clears.

The answer to your question is on the API page:

This event is delivered to a display object when …  removed … This is useful if you have cleanup …

In the code above, all enemies have a finalize listener attached, so when they are deleted it executes and they remove their reference from the enemies table.

Open up a blank project and put this in main.lua to help you understand.

local obj = display.newCircle( 100, 100, 10 ) function obj.finalize( self ) print (" Deleting object ", self, " @ ", system.getTimer() ) end obj:addEventListener("finalize") print("Created and set up object ", obj, " @ ", system.getTimer() ) display.remove(obj)

Thank you!

Thanks!!!


compare and contrast essay sample