ID:2849675
 
Redundant
Applies to:DM Language
Status: Redundant

This feature has already been implemented, or is already achievable with existing methods.
According to this post: https://www.byond.com/forum/post/2829352?first_unread=1

for(var/obj/machinery/door/D in world)


is quite slow because it loops over all objs (or all atoms) in the world, so Goonstation has come up with some annoying workaround - they make a list of all atoms of each type they want to loop over.

I suggest that it should be the engine's job to make it work fast, not the developer's job. It would require adding two pointers to each atom, forming a linked list through all atoms of the same type. Subtypes could be handled by looping over subtypes, since subtypes are usually much less numerous than objects.

Alternatively, the compiler could look at which types are used in for loops (since it can see all the loops) and create a list for each of those types and its subtypes. That would avoid looping over subtypes, but may increase memory usage more. I expect that memory usage won't be a problem either way.
"is quite slow because it loops over all objs (or all atoms) in the world, so Goonstation has come up with some annoying workaround - they make a list of all atoms of each type they want to loop over."

This sounds like the only solution that makes sense. If you want to loop over very specific sets of objects, why wouldn't you have to keep track of them?
Two pointers per object in the world is a lot more memory than a list containing one pointer per relevant object in the world. It's always been known that you should keep lists of things you want to loop over rather than using `in world`.
For comparison, the engine allows you to loop over ranges and views without internally looping over all objects and then checking which ones are in range.
In response to Immibis
Immibis wrote:
For comparison, the engine allows you to loop over ranges and views without internally looping over all objects and then checking which ones are in range.

With range, you're simply checking every loc that fits within the scope of the range for a specific object.
Right. The engine keeps a data structure that contains all of the objects per turf, so it can efficiently look up objects in the world in range. If the game uses loops by type, it should also keep a data structure that contains all the objects by type, so it can efficiently look up objects in the world by type.
In response to Immibis
Immibis wrote:
Right. The engine keeps a data structure that contains all of the objects per turf, so it can efficiently look up objects in the world in range. If the game uses loops by type, it should also keep a data structure that contains all the objects by type, so it can efficiently look up objects in the world by type.

I'm not sure why this is something to argue about.

But your example doesn't really make sense imo.


"
For comparison, the engine allows you to loop over ranges and views without internally looping over all objects and then checking which ones are in range."

Like why would it loop over all objects, when you specifically ask it loop over a designated range?

The way it works now it would still perform a loop for all of the turf's content regardless.

So if turf A contained 100 or so atoms, range would still have to run a check for each atom in the turf's contents to make sure it fit the type that you were looking for.
Like why would it loop over all objects, when you specifically ask it loop over a designated range?

Yes, that's what I'm saying. Why would it loop over all objects, when you specifically ask it to loop over a designated type?

I'm still not sure why you want to argue about this. Further communication will be ignored to avoid spamming this thread. Ask it on Discord.
The reason it's relatively easy to look up all objects in a particular range is because the ability to find objects on particular turfs is kind of an important core feature.

Looking up all objects of a specific type in the entire world is, in contrast, not something that's frequently done, especially in a very large world like the kind you see in SS13. Yes, it would be possible to allocate arrays for each prototype with a list of primitive IDs, and keep those arrays updated as objects are created and destroyed. Practical? No way. It adds overhead to creation and deletion that most games would never need.

The correct solution is the one that others have presented: handling this with a soft-coded list for the very few situations where you might need to loop through all objects of a type.

Just because the engine and language make a certain thing possible does not mean the engine should go to extraordinary lengths to make that thing efficient. In any programming language it's important for the programmer to make common-sense decisions about how to improve efficiency.
Note that it only needs to happen for types that are used in these loops at compile-time.
In response to Immibis
That's adding yet another layer of complication, or rather several. Now you have the compiler having to mark down, and save in the .dmb, that users are looping through all objects of a given prototype and therefore all objects of that type or a subtype should be stored in a given list. Then at runtime, on any object creation or destruction you'd have to check the prototype and all of its parents, look for that flag, and see if the object ID needs to be added to or removed from the lists for these flagged types.

Theoretically some of that could be improved by not looking at parents, but marking all subtypes as needing such a list, and then when doing the loop-through-all on the main type the engine could do an internal typesof() and grab the list contents of all the subtypes' lists. Which isn't efficient either.

As Atomix said in BYONDiscord, you're looking for a solution to a problem that only masks poor programming practices. There may well be reasons to occasionally use such a practice, but if you're going to be doing it often or in a huge world, it's up to the programmer to do it a smarter way.
In response to Lummox JR
Lummox JR wrote:
As Atomix said in BYONDiscord, you're looking for a solution to a problem that only masks poor programming practices.

Exactly this.

Lummox JR resolved issue (Redundant)