ID:2717237
 
Resolved
Adding an object to all turfs' visual contents and then later setting its vis_locs to null caused a massive slowdown, which was bigger on larger maps. While there is still a bit of unavoidable grind involved in removing the same object from the visual contents of every turf on the map, the speed of the process has been greatly improved.
BYOND Version:514
Operating System:Windows 10 Pro 64-bit
Web Browser:Chrome 93.0.4577.82
Applies to:Dream Daemon
Status: Resolved (514.1567)

This issue has been resolved.
Descriptive Problem Summary:

When clearing the vis_locs list the client will get progressively slower the bigger the list it's trying to clear, eventually just hanging until the OS kills the process.


Code Snippet (if applicable) to Reproduce Problem:
mob
verb
AddObject()
if(!dummy)
dummy = new()
dummy.icon = 'test.dmi'
dummy.vis_locs = block(locate(1,1,1),locate(world.maxx,world.maxy,1))
RemoveObject()
if(dummy)
dummy.vis_locs = null


Expected Results:

Parity with the speed of adding the visual objects to removing them, and definitely not a hang.

Actual Results:

Adding the list using block() works great, almost instant up to some massive lists. The same operation in reverse murders the server's resources until it just stalls.

Does the problem occur:
Every time? Or how often? Every time.
In other games? Yes
In other user accounts? Yes
On other computers? Yes

When does the problem NOT occur?

You can iterate over vis_locs and manually remove items, but there's something fishy going on behind the scenes where adding/removing are vastly different in speed and resource usage.

Test Case:

https://drive.google.com/file/d/ 12gPzRPE-MypX_uNUbqy_Pb_l-4T8zenu/view?usp=sharing

Instructions: Include map_hangs.dmm and run, use the "AddObject" verb then use the "RemoveObject" verb. Client hangs. Map 100x100 smaller doesn't cause the forever hang (but it takes a few seconds for it to unfreeze).

This obviously isn't the ideal usage of vis_contents/vis_locs, but it probably shouldn't kill the server to do it, even if it just runtimes out on being too large to remove or something. Ideally though, it would work as good as adding them to the list.
On the nohang map I'm seeing a very slow loop, so I think a big part of the issue is there's a loop with bad O(N^2) performance. But there appears to be more to it than that because even when I change the loop order it's quite slow. I'm working on a fix now.
I've made a massive improvement to the removal time and think this will solve a number of issues. However, there is still a very noticeable delay in the removal, of several seconds.

The reason the delay exists appears to simply be that removing turf data is a slightly more involved process than adding it.
Lummox JR resolved issue with message:
Adding an object to all turfs' visual contents and then later setting its vis_locs to null caused a massive slowdown, which was bigger on larger maps. While there is still a bit of unavoidable grind involved in removing the same object from the visual contents of every turf on the map, the speed of the process has been greatly improved.