diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/ChunkAccessMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/ChunkAccessMixin.java new file mode 100644 index 00000000..a5952a5d --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/ChunkAccessMixin.java @@ -0,0 +1,36 @@ +package org.embeddedt.modernfix.common.mixin.perf.ticking_chunk_alloc; + +import net.minecraft.world.level.chunk.ChunkAccess; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.Collections; +import java.util.Map; + +@Mixin(value = ChunkAccess.class, priority = 800) +public class ChunkAccessMixin { + @Shadow @Final private Map, ?> structuresRefences; + private Map, ?> mfix$structureRefsView; + + /** + * @author embeddedt + * @reason Cache returned map view to avoid allocations, return empty map when possible + * so that iterator() calls don't allocate + *
+ * Note: technically, this introduces an API change, as the return value may no longer be a live view + * of the structure references of the chunk. It's unlikely this will affect anything in practice. + */ + @Overwrite + public Map, ?> getAllReferences() { + if(this.structuresRefences.isEmpty()) { + return Collections.emptyMap(); + } + Map, ?> view = this.mfix$structureRefsView; + if(view == null) { + this.mfix$structureRefsView = view = Collections.unmodifiableMap(this.structuresRefences); + } + return view; + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/ChunkGeneratorMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/ChunkGeneratorMixin.java deleted file mode 100644 index 193995f4..00000000 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/ChunkGeneratorMixin.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.embeddedt.modernfix.common.mixin.perf.ticking_chunk_alloc; - -import net.minecraft.world.level.chunk.ChunkGenerator; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -import java.util.Collections; -import java.util.Map; -import java.util.Set; - -@Mixin(ChunkGenerator.class) -public class ChunkGeneratorMixin { - /** - * @author embeddedt - * @reason Avoid allocation if the chunk contains no structures - */ - @Redirect(method = "getMobsAt", at = @At(value = "INVOKE", target = "Ljava/util/Map;entrySet()Ljava/util/Set;"), require = 0) - private Set> avoidSetAllocation(Map, ?> instance) { - if(instance.isEmpty()) { - return Collections.emptySet(); - } else { - return instance.entrySet(); - } - } -}