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 <gegy1000@gmail.com>
Co-authored-by: Dylan Xaldin <Puremin0rez515@gmail.com>
Co-authored-by: pop4959 <pop4959@gmail.com>

diff --git a/src/main/java/net/minecraft/world/level/biome/TheEndBiomeSource.java b/src/main/java/net/minecraft/world/level/biome/TheEndBiomeSource.java
index d090bdc063480ee6e28b0d60447ebe4063e6d688..ff0255e7f3c75e9972e8516058c234c7b58a0bd7 100644
--- a/src/main/java/net/minecraft/world/level/biome/TheEndBiomeSource.java
+++ b/src/main/java/net/minecraft/world/level/biome/TheEndBiomeSource.java
@@ -29,6 +29,16 @@ public class TheEndBiomeSource extends BiomeSource {
     private final Biome midlands;
     private final Biome islands;
     private final Biome barrens;
+    // 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<java.util.Map<SimplexNoise, NoiseCache>> noiseCache = ThreadLocal.withInitial(java.util.WeakHashMap::new);
+    // Paper end
 
     public TheEndBiomeSource(Registry<Biome> biomeRegistry, long seed) {
         this(biomeRegistry, seed, biomeRegistry.getOrThrow(Biomes.THE_END), biomeRegistry.getOrThrow(Biomes.END_HIGHLANDS), biomeRegistry.getOrThrow(Biomes.END_MIDLANDS), biomeRegistry.getOrThrow(Biomes.SMALL_END_ISLANDS), biomeRegistry.getOrThrow(Biomes.END_BARRENS));
@@ -88,12 +98,26 @@ public class TheEndBiomeSource extends BiomeSource {
         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;
