diff --git a/paper-server/patches/sources/net/minecraft/world/level/levelgen/DensityFunctions.java.patch b/paper-server/patches/sources/net/minecraft/world/level/levelgen/DensityFunctions.java.patch index d04089f01..3f778b542 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/levelgen/DensityFunctions.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/levelgen/DensityFunctions.java.patch @@ -1,6 +1,23 @@ --- a/net/minecraft/world/level/levelgen/DensityFunctions.java +++ b/net/minecraft/world/level/levelgen/DensityFunctions.java -@@ -521,7 +521,7 @@ +@@ -509,6 +509,16 @@ + ); + private static final float ISLAND_THRESHOLD = -0.9F; + private final SimplexNoise islandNoise; ++ // Paper start - Perf: Optimize end generation ++ private static final class NoiseCache { ++ public long[] keys = new long[8192]; ++ public float[] values = new float[8192]; ++ public NoiseCache() { ++ java.util.Arrays.fill(keys, Long.MIN_VALUE); ++ } ++ } ++ private static final ThreadLocal> noiseCache = ThreadLocal.withInitial(java.util.WeakHashMap::new); ++ // Paper end - Perf: Optimize end generation + + public EndIslandDensityFunction(long seed) { + RandomSource randomSource = new LegacyRandomSource(seed); +@@ -521,15 +531,29 @@ int j = z / 2; int k = x % 2; int l = z % 2; @@ -8,4 +25,28 @@ + float f = 100.0F - Mth.sqrt((long) x * (long) x + (long) z * (long) z) * 8.0F; // Paper - cast ints to long to avoid integer overflow f = Mth.clamp(f, -100.0F, 80.0F); ++ NoiseCache cache = noiseCache.get().computeIfAbsent(sampler, noiseKey -> new NoiseCache()); // Paper - Perf: Optimize end generation for (int m = -12; m <= 12; m++) { + for (int n = -12; n <= 12; n++) { + long o = (long)(i + m); + long p = (long)(j + n); +- if (o * o + p * p > 4096L && sampler.getValue((double)o, (double)p) < -0.9F) { +- float g = (Mth.abs((float)o) * 3439.0F + Mth.abs((float)p) * 147.0F) % 13.0F + 9.0F; ++ // Paper start - Perf: Optimize end generation by using a noise cache ++ long key = net.minecraft.world.level.ChunkPos.asLong((int) o, (int) p); ++ int index = (int) it.unimi.dsi.fastutil.HashCommon.mix(key) & 8191; ++ float g = Float.MIN_VALUE; ++ if (cache.keys[index] == key) { ++ g = cache.values[index]; ++ } else { ++ if (o * o + p * p > 4096L && sampler.getValue((double)o, (double)p) < -0.9F) { ++ g = (Mth.abs((float)o) * 3439.0F + Mth.abs((float)p) * 147.0F) % 13.0F + 9.0F; ++ } ++ cache.keys[index] = key; ++ cache.values[index] = g; ++ } ++ if (g != Float.MIN_VALUE) { ++ // Paper end - Perf: Optimize end generation + float h = (float)(k - m * 2); + float q = (float)(l - n * 2); + float r = 100.0F - Mth.sqrt(h * h + q * q) * g;