mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-21 07:59:26 +00:00
* uwu * reorder * Change author * Sync upstream * Lithium: equipment tracking * Faster CraftServer#getworlds list creation Co-Authored-By: Kobe ⑧ <102713261+HaHaWTH@users.noreply.github.com>
138 lines
6.6 KiB
Diff
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;
|
|
+ }
|
|
+}
|