From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: SuperCoder7979 <25208576+SuperCoder7979@users.noreply.github.com> Date: Tue, 3 Nov 2020 23:48:05 -0600 Subject: [PATCH] Significantly improve performance of the end generation This patch implements a noise cache for the end which significantly reduces the computation time of generation. This results in about a 3x improvement. Original code by SuperCoder7979 and Gegy in Lithium, licensed under LGPL-3.0 (Source: https://github.com/jellysquid3/lithium-fabric) Co-authored-by: Gegy Co-authored-by: Dylan Xaldin Co-authored-by: pop4959 diff --git a/src/main/java/net/minecraft/world/level/levelgen/DensityFunctions.java b/src/main/java/net/minecraft/world/level/levelgen/DensityFunctions.java index 6825feea42667a0f14c4c730e5f1ac970c654c56..1d00c019eb976de22be6e5e1f3632ca0c00d77ea 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/DensityFunctions.java +++ b/src/main/java/net/minecraft/world/level/levelgen/DensityFunctions.java @@ -489,6 +489,16 @@ public final class DensityFunctions { public static final KeyDispatchDataCodec CODEC = KeyDispatchDataCodec.of(MapCodec.unit(new DensityFunctions.EndIslandDensityFunction(0L))); private static final float ISLAND_THRESHOLD = -0.9F; private final SimplexNoise islandNoise; + // Paper start + 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 public EndIslandDensityFunction(long seed) { RandomSource randomSource = new LegacyRandomSource(seed); @@ -504,12 +514,26 @@ public final class DensityFunctions { float f = 100.0F - Mth.sqrt((long) i * (long) i + (long) j * (long) j) * 8.0F; // Paper - cast ints to long to avoid integer overflow f = Mth.clamp(f, -100.0F, 80.0F); + NoiseCache cache = noiseCache.get().computeIfAbsent(simplexNoise, noiseKey -> new NoiseCache()); // Paper for(int o = -12; o <= 12; ++o) { for(int p = -12; p <= 12; ++p) { long q = (long)(k + o); long r = (long)(l + p); - if (q * q + r * r > 4096L && simplexNoise.getValue((double)q, (double)r) < (double)-0.9F) { - float g = (Mth.abs((float)q) * 3439.0F + Mth.abs((float)r) * 147.0F) % 13.0F + 9.0F; + // Paper start - Significantly improve end generation performance by using a noise cache + long key = net.minecraft.world.level.ChunkPos.asLong((int) q, (int) r); + 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 (q * q + r * r > 4096L && simplexNoise.getValue((double)q, (double)r) < (double)-0.9F) { + g = (Mth.abs((float) q) * 3439.0F + Mth.abs((float) r) * 147.0F) % 13.0F + 9.0F; + } + cache.keys[index] = key; + cache.values[index] = g; + } + if (g != Float.MIN_VALUE) { + // Paper end float h = (float)(m - o * 2); float s = (float)(n - p * 2); float t = 100.0F - Mth.sqrt(h * h + s * s) * g;