Skip to content

Conversation

VoidLeech
Copy link
Collaborator

Fixes - #9284
Is probably sufficient to resolve - #5785

So as pointed out in the more recent issue, we were performing a very expensive List#contains call, which dates back to fca3b74. I don't exactly see how that line ever helped with preventing infinite looping, it just seems to bypass the contains check for logs that are in the visited set (simpler solution to that though: don't add them to the visited set then) so that we can still search their neighbours.
I've resolved this by just always going to forNeighbours if something is in the frontier (and passes the relevant checks at that stage, ofc). The visited contains check (add) still needs to be done though, which brings us to improvement number 2:

The more recent issue also pointed out very high numbers of leaves and logs in the respective lists, and if we actually looked at the number of unique logs and leaves in them, they are way too high, this is just from a single oak tree, #unique after the comma:

[01:11:06] [Server thread/WARN] [co.si.cr.Create/]: Initial Tally
[01:11:06] [Server thread/WARN] [co.si.cr.Create/]: Logs: 4, 4   
[01:11:06] [Server thread/WARN] [co.si.cr.Create/]: Final Tally  
[01:11:06] [Server thread/WARN] [co.si.cr.Create/]: Logs: 4, 4
[01:11:06] [Server thread/WARN] [co.si.cr.Create/]: Leaves: 229, 55
[01:11:06] [Server thread/WARN] [co.si.cr.Create/]: Attachments: 0, 0

And mangroves are excessive:

[02:20:17] [Server thread/WARN] [co.si.cr.Create/]: Initial Tally
[02:20:17] [Server thread/WARN] [co.si.cr.Create/]: Logs: 43, 43 
[02:20:17] [Server thread/WARN] [co.si.cr.Create/]: After Roots  
[02:20:17] [Server thread/WARN] [co.si.cr.Create/]: Logs: 468, 64
[02:20:17] [Server thread/WARN] [co.si.cr.Create/]: Final Tally          
[02:20:17] [Server thread/WARN] [co.si.cr.Create/]: Logs: 468, 64        
[02:20:17] [Server thread/WARN] [co.si.cr.Create/]: Leaves: 3486, 586    
[02:20:17] [Server thread/WARN] [co.si.cr.Create/]: Attachments: 191, 191

frontier.addAll(logs);
if (hasRoots) {
while (!frontier.isEmpty()) {
BlockPos currentPos = frontier.remove(0);
if (!logs.contains(currentPos) && !visited.add(currentPos))
continue;
BlockState currentState = reader.getBlockState(currentPos);
if (!isRoot(currentState))
continue;
logs.add(currentPos);
forNeighbours(currentPos, visited, SearchDirection.DOWN, p -> frontier.add(new BlockPos(p)));

Because some roots are already in the list of logs, they fail the !contains check, and get added to the list again. Also, they will likely have downward neighbours that are also already in the list. The leaves have a similar problem where the same blockpos can get added to the frontier (and leaves list) from multiple directions before it's ever added to the visited set, exacerbated by the fact that there will be duplicate roots that all do this. So solution to both cases, move the visited check/addition to directly before adding to the frontier. Do need to keep a copy of the initial logs list (as a set though, obviously) to ensure we can still add new roots while not duplicating any.

Tests were performed on this line of 8 mangroves grown into each other on a non-mob spawning superflat world, inside my dev env, which is already quite stuttery compared to a production environment.
image

Before:
https://spark.lucko.me/1Jtr6zYYdE, 97% of SawBlockEntity#onBlockbroken is taken up by TreeCutter#findTree

[01:14:44] [Server thread/WARN] [co.si.cr.Create/]: Initial Tally
[01:14:44] [Server thread/WARN] [co.si.cr.Create/]: Logs: 186, 186
[01:14:52] [Server thread/WARN] [co.si.cr.Create/]: After Roots
[01:14:52] [Server thread/WARN] [co.si.cr.Create/]: Logs: 11366, 328
[01:14:54] [Server thread/WARN] [co.si.cr.Create/]: Final Tally        
[01:14:54] [Server thread/WARN] [co.si.cr.Create/]: Logs: 11366, 328   
[01:14:54] [Server thread/WARN] [co.si.cr.Create/]: Leaves: 11788, 1491
[01:14:54] [Server thread/WARN] [co.si.cr.Create/]: Attachments: 355, 355

After:
https://spark.lucko.me/SpQK7Gsk5b, only 13% now.

[01:24:31] [Server thread/WARN] [co.si.cr.Create/]: Initial Tally 
[01:24:31] [Server thread/WARN] [co.si.cr.Create/]: Logs: 186, 186
[01:24:31] [Server thread/WARN] [co.si.cr.Create/]: After Roots   
[01:24:31] [Server thread/WARN] [co.si.cr.Create/]: Logs: 328, 328
[01:24:31] [Server thread/WARN] [co.si.cr.Create/]: Final Tally       
[01:24:31] [Server thread/WARN] [co.si.cr.Create/]: Logs: 328, 328    
[01:24:31] [Server thread/WARN] [co.si.cr.Create/]: Leaves: 1491, 1491
[01:24:31] [Server thread/WARN] [co.si.cr.Create/]: Attachments: 358, 358

@VoidLeech VoidLeech added pr type: fix PR fixes a bug pr type: feature PR adds a new feature or changes an existing feature labels Oct 5, 2025
@IThundxr
Copy link
Member

Thanks!

@IThundxr IThundxr added this pull request to the merge queue Oct 18, 2025
Merged via the queue into Creators-of-Create:mc1.20.1/dev with commit 3ae754b Oct 18, 2025
3 checks passed
@VoidLeech VoidLeech deleted the mc1.20.1/treefinder-optimization branch October 18, 2025 17:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr type: feature PR adds a new feature or changes an existing feature pr type: fix PR fixes a bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants