ID:149919
 
I was wondering about how efficient (cpu draining) using loops like this are:
for(var/obj/O in world)

Basically, even though I may only have 3-5 objects in the entire world will this still be inefficient?

I guess I need to know what it does in the loop, does it actually check every turf, mob and obj for obj's or does it keep track of where all objects, mobs, turfs, ect. are as you create/move them so it doesn't have to look for the objects?
English wrote:
I was wondering about how efficient (cpu draining) using loops like this are:
for(var/obj/O in world)

Basically, even though I may only have 3-5 objects in the entire world will this still be inefficient?

I guess I need to know what it does in the loop, does it actually check every turf, mob and obj for obj's or does it keep track of where all objects, mobs, turfs, ect. are as you create/move them so it doesn't have to look for the objects?

Perfect, I just got done thinking about this. In order to cut down that specific statement you gave, you must be more specific when writing it. Let me give you an example:

This code is laggy

proc
lagster()
for(var/obj/A in world)
if(A.z == 1)
del(A)

This code is laggy, because it loops through all objs, even objs inside of players and only deletes the ones in the first layer.
This following code will be considerably faster, as lets say we only want to look at all objects in the first layer, this would not loop through objects inside of players. This skips tons of processing time, and makes it a lot faster.

proc
nolag()
for(var/obj/A in block(locate(1,1,1),locate(world.maxx,world.maxy,1)))
del(A)

this code deletes every object in the 1rst layer! It was a lot faster, because we got rid of all the objects we didnt need to delete in the for() proc.


on another note, let me explain a few more things.

when you use the statement

for(var/obj/O in world)

that loooks for every single object in the entire game, no matter where it is or what its doing. If its on a turf, it loops through it, if its in a player, it loops through it, if you have objects that hold other objects, it loops through all of them as well. When you cut out which objects you are looping through, it goes much much faster. this can be done several ways, and most efficiently with lists or block statements(depending on the situation).

one thing that is good to know, is when an object goes into another object, or a mob, its x y and z variable is set to 0. Thats why when we used the block() statement, we looked at all objects in the first layer. Objects inside of other things have a 0 z variable, and this gets rid of a considerable amount. We also eliminated a lot of objects that were on other z layers, as we were only looking for objects on the first layer.

FIREking
In response to FIREking
Thank you very much! I've got quite a few of those loops in my code and wasn't sure of any better (more efficient) way to do it.

That's exactly what I needed, I remember reading about blocks but it never even occured to me to use them that way.

Well, I suppose I have just one remaining question then. From what you said it sounds like the loop does actually know where the obj's are so it can access them quickly but it still has to go through all objs if you use in world.

So would I be correct in saying that if I only have 5-10 objects in the entire world that it would do it quickly despite checking the entire world for them?

In the game I'm making the battle field is cleared of objs and mobs after each battle and the world map (the main map where you travel in) there are no obj's, only mobs and turfs. I suppose there could be a maximum of about 100 objs if 18 people are simultaneously battling (currently only have 9 arenas, 2 people each) so it would still be worth doing it in blocks as you suggested.
In response to English
Here's an even more efficient way... make global lists of objects/mobs/whatevers that have to be looped through frequently.

for (var/mob/spooglesaurus/s in myspooglesauri)
In response to Lesbian Assassin
I think that will work best for a few of my loops but the rest will probably need to use at least the block method.

Again, thanks for the good suggestions :)
In response to FIREking
I tried using block in the loop but it doesn't see the obj's contained in the block. I think this is because there are only turfs included in the block and not the contents of those turfs.

Is there anyway to get arround this other than checking each of the turfs contents with if statements?
English wrote:
I was wondering about how efficient (cpu draining) using loops like this are:
for(var/obj/O in world)

Basically, even though I may only have 3-5 objects in the entire world will this still be inefficient?

No, that statement is fine. Objects and mobs are stored in their own separate table, and the lookup speed will not scale with the map size.
In response to Tom
Ah ok, that makes sense. Thanks for the clarification :)
In response to English
English wrote:
I tried using block in the loop but it doesn't see the obj's contained in the block. I think this is because there are only turfs included in the block and not the contents of those turfs.

Is there anyway to get arround this other than checking each of the turfs contents with if statements?

You are correct, and i only noticed this after i posted. I am sorry, hopefully we can request the return list for block() to report all atoms contained in the block!

FIREking
In response to FIREking
Oh well, live and learn, and then get loves...too much TV...ack!

At least we're more familiar with block now, never hurts to know about another feature :)

That feature would help eliminate the need for using things like:
if(O.z == M.z)
To make sure it's on the right layer.

The feature could work something like this:
for(var/obj/O in z)

I suppose it would depend on how the table of objects is organized. If it's organized according to location already then it would probably be fairly simple to make.

Actually, now that I think about it I could probably make a program that does that automatically. Just have a global two dimensional array (or I suppose list in byond) and just connect it to obj's by using obj's new proc to organize them by z layer. I'll start tinkering with it!