From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paul Sauve Date: Thu, 4 Feb 2021 23:24:20 -0600 Subject: [PATCH] Reduce allocs & improve perf of StructureManager Focuses on two methods, getStructureStarts & getFeatureStarts. For getStructureStarts, it inlines getFeatureStarts so it doesn't have to calculate an entire list when it returns early. As well, it uses a LongIterator in order to not allocate longs for each position. Airplane Copyright (C) 2020 Technove LLC This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . diff --git a/src/main/java/net/minecraft/world/level/StructureManager.java b/src/main/java/net/minecraft/world/level/StructureManager.java index 43418273f00f3703c7bd86586847d469af92c18f..d11e79093f9a5121c98b7da840bc79d204895b65 100644 --- a/src/main/java/net/minecraft/world/level/StructureManager.java +++ b/src/main/java/net/minecraft/world/level/StructureManager.java @@ -16,6 +16,11 @@ import net.minecraft.world.level.levelgen.feature.StructureGenerator; import net.minecraft.world.level.levelgen.structure.StructurePiece; import net.minecraft.world.level.levelgen.structure.StructureStart; +// Airplane start +import it.unimi.dsi.fastutil.longs.LongIterator; +import it.unimi.dsi.fastutil.longs.LongSet; +// Airplane end + public class StructureManager { private final GeneratorAccess a; public GeneratorAccess getLevel() { return a; } // Paper - OBFHELPER @@ -52,13 +57,15 @@ public class StructureManager { public java.util.List> getFeatureStarts(SectionPosition sectionPosition, StructureGenerator structureGenerator, IWorldReader world) { // Tuinity end - add world parameter java.util.List> list = new ObjectArrayList<>(); - for (Long curLong: (world == null ? getLevel() : world).getChunkAt(sectionPosition.a(), sectionPosition.c(), ChunkStatus.STRUCTURE_REFERENCES).b(structureGenerator)) { // Tuinity - fix deadlock on world gen - chunk can be unloaded while generating, so we should be using the generator's regionlimitedaccess so we always get the chunk - SectionPosition sectionPosition1 = SectionPosition.a(new ChunkCoordIntPair(curLong), 0); + // Airplane start - skip allocating Longs + (world == null ? getLevel() : world).getChunkAt(sectionPosition.a(), sectionPosition.c(), ChunkStatus.STRUCTURE_REFERENCES).b(structureGenerator).forEach((java.util.function.LongConsumer) curLong -> { + SectionPosition sectionPosition1 = SectionPosition.a(ChunkCoordIntPair.getX(curLong), 0, ChunkCoordIntPair.getZ(curLong)); // don't allocate ChunkCoordIntPair StructureStart structurestart = a(sectionPosition1, structureGenerator, getLevel().getChunkAt(sectionPosition1.a(), sectionPosition1.c(), ChunkStatus.STRUCTURE_STARTS)); if (structurestart != null && structurestart.e()) { list.add(structurestart); } - } + }); + // Airplane end return list; } // Paper end @@ -86,7 +93,18 @@ public class StructureManager { } public StructureStart getStructureStarts(BlockPosition blockposition, boolean flag, StructureGenerator structuregenerator, IWorldReader world) { // Paper start - remove structure streams - for (StructureStart structurestart : getFeatureStarts(SectionPosition.a(blockposition), structuregenerator, world)) { // Tuinity end - add world parameter + // Airplane start - inline getFeatureStarts to skip creating the list + SectionPosition sectionPosition = SectionPosition.a(blockposition); + + // use iterator here instead of forEach like in getFeatureStarts so we can return early + LongSet longSet = (world == null ? getLevel() : world).getChunkAt(sectionPosition.a(), sectionPosition.c(), ChunkStatus.STRUCTURE_REFERENCES).b(structuregenerator); + LongIterator iterator = longSet.iterator(); + while (iterator.hasNext()) { + long curLong = iterator.nextLong(); + SectionPosition sectionPosition1 = SectionPosition.a(ChunkCoordIntPair.getX(curLong), 0, ChunkCoordIntPair.getZ(curLong)); // don't allocate ChunkCoordIntPair + StructureStart structurestart = a(sectionPosition1, structuregenerator, getLevel().getChunkAt(sectionPosition1.a(), sectionPosition1.c(), ChunkStatus.STRUCTURE_STARTS)); + if (structurestart != null && structurestart.e()) { + if (structurestart.c().b(blockposition)) { if (!flag) { return structurestart; @@ -97,7 +115,10 @@ public class StructureManager { } } } + + } } + // Airplane end return StructureStart.a; // Paper end }