9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-21 07:59:26 +00:00
Files
Leaf/patches/server/0107-Reduce-worldgen-allocations.patch
Dreeam 27134f699a Added some optimizations (#164)
* uwu

* reorder

* Change author

* Sync upstream

* Lithium: equipment tracking

* Faster CraftServer#getworlds list creation

Co-Authored-By: Kobe ⑧ <102713261+HaHaWTH@users.noreply.github.com>
2024-11-14 06:50:59 -05:00

138 lines
6.6 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com>
Date: Fri, 14 Jun 2024 23:19:55 +0800
Subject: [PATCH] Reduce worldgen allocations
This change optimizes the way SurfaceRules update their biome supplier,avoiding unnecessary object creations and thus reducing memory allocations
during world generation. The update method now reuses the existing PositionalBiomeGetter object if it's already present, otherwise it
initializes a new one.
Additionally, the tryApply method in SurfaceRules now avoids iterator
allocation by directly accessing the rules list, which further contributes
to reducing garbage collection pressure during world generation.
diff --git a/src/main/java/net/minecraft/world/level/levelgen/NoiseChunk.java b/src/main/java/net/minecraft/world/level/levelgen/NoiseChunk.java
index 5e89428321d91edb893826b0eb0b9050d327d310..3e8882e4779d6037025e7ee26ebbb46a55a7e52d 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/NoiseChunk.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/NoiseChunk.java
@@ -359,7 +359,14 @@ public class NoiseChunk implements DensityFunction.ContextProvider, DensityFunct
}
protected DensityFunction wrap(DensityFunction function) {
- return this.wrapped.computeIfAbsent(function, this::wrapNew);
+ // Leaf start - Avoid lambda allocation
+ DensityFunction func = this.wrapped.get(function);
+ if (func == null) {
+ func = this.wrapNew(function);
+ this.wrapped.put(function, func);
+ }
+ return func;
+ // Leaf end - Avoid lambda allocation
}
private DensityFunction wrapNew(DensityFunction function) {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/SurfaceRules.java b/src/main/java/net/minecraft/world/level/levelgen/SurfaceRules.java
index 7ba3a3ca57b55f796a90b700b930f365c3508484..2a0cd84c8a530bc34b6bc8034bd7156131837139 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/SurfaceRules.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/SurfaceRules.java
@@ -314,8 +314,14 @@ public class SurfaceRules {
}
protected void updateY(int stoneDepthAbove, int stoneDepthBelow, int fluidHeight, int blockX, int blockY, int blockZ) {
- this.lastUpdateY++;
- this.biome = Suppliers.memoize(() -> this.biomeGetter.apply(this.pos.set(blockX, blockY, blockZ)));
+ // Leaf start - Reuse supplier object instead of creating new ones every time
+ ++this.lastUpdateY;
+ Supplier<Holder<Biome>> getter = this.biome;
+ if (getter == null) {
+ this.biome = getter = new org.dreeam.leaf.util.biome.PositionalBiomeGetter(this.biomeGetter, this.pos);
+ }
+ ((org.dreeam.leaf.util.biome.PositionalBiomeGetter)getter).update(blockX, blockY, blockZ);
+ // Leaf end - Reuse supplier object instead of creating new ones every time
this.blockY = blockY;
this.waterHeight = fluidHeight;
this.stoneDepthBelow = stoneDepthBelow;
@@ -577,8 +583,12 @@ public class SurfaceRules {
@Nullable
@Override
public BlockState tryApply(int x, int y, int z) {
- for (SurfaceRules.SurfaceRule surfaceRule : this.rules) {
- BlockState blockState = surfaceRule.tryApply(x, y, z);
+ // Leaf start - Avoid iterator allocation
+ int size = this.rules.size();
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0; i < size; i++) {
+ BlockState blockState = this.rules.get(i).tryApply(x, y, z);
+ // Leaf end - Avoid iterator allocation
if (blockState != null) {
return blockState;
}
diff --git a/src/main/java/net/minecraft/world/level/levelgen/material/MaterialRuleList.java b/src/main/java/net/minecraft/world/level/levelgen/material/MaterialRuleList.java
index afdbc74a3012fa717f59ecef613567338d285b7b..088e02e0941341fea958413176f49ae262e04d2a 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/material/MaterialRuleList.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/material/MaterialRuleList.java
@@ -10,13 +10,16 @@ public record MaterialRuleList(List<NoiseChunk.BlockStateFiller> materialRuleLis
@Nullable
@Override
public BlockState calculate(DensityFunction.FunctionContext pos) {
- for (NoiseChunk.BlockStateFiller blockStateFiller : this.materialRuleList) {
- BlockState blockState = blockStateFiller.calculate(pos);
- if (blockState != null) {
- return blockState;
- }
+ // Leaf start - Avoid iterator allocation
+ BlockState blockState = null;
+ int s = this.materialRuleList.size();
+
+ for (int i = 0; blockState == null && i < s; i++) {
+ NoiseChunk.BlockStateFiller blockStateFiller = this.materialRuleList.get(i);
+ blockState = blockStateFiller.calculate(pos);
}
- return null;
+ return blockState;
+ // Leaf end - Avoid iterator allocation
}
}
diff --git a/src/main/java/org/dreeam/leaf/util/biome/PositionalBiomeGetter.java b/src/main/java/org/dreeam/leaf/util/biome/PositionalBiomeGetter.java
new file mode 100644
index 0000000000000000000000000000000000000000..3683c61ebc673cf5d2f8197fffdf44270f1287f4
--- /dev/null
+++ b/src/main/java/org/dreeam/leaf/util/biome/PositionalBiomeGetter.java
@@ -0,0 +1,36 @@
+package org.dreeam.leaf.util.biome;
+
+import net.minecraft.core.BlockPos;
+import net.minecraft.core.Holder;
+import net.minecraft.world.level.biome.Biome;
+
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+public class PositionalBiomeGetter implements Supplier<Holder<Biome>> {
+ private final Function<BlockPos, Holder<Biome>> biomeGetter;
+ private final BlockPos.MutableBlockPos pos;
+ private int nextX, nextY, nextZ;
+ private volatile Holder<Biome> curBiome;
+
+ public PositionalBiomeGetter(Function<BlockPos, Holder<Biome>> biomeGetter, BlockPos.MutableBlockPos pos) {
+ this.biomeGetter = biomeGetter;
+ this.pos = pos;
+ }
+
+ public void update(int nextX, int nextY, int nextZ) {
+ this.nextX = nextX;
+ this.nextY = nextY;
+ this.nextZ = nextZ;
+ this.curBiome = null;
+ }
+
+ @Override
+ public Holder<Biome> get() {
+ Holder<Biome> biome = curBiome;
+ if (biome == null) {
+ curBiome = biome = biomeGetter.apply(pos.set(nextX, nextY, nextZ));
+ }
+ return biome;
+ }
+}