From 1f8d9a710f854a25bd8590ba70410b775efb95e4 Mon Sep 17 00:00:00 2001 From: dfsek Date: Sat, 21 Nov 2020 16:14:09 -0700 Subject: [PATCH] Implement NoiseFunction2 cache --- .../com/dfsek/terra/math/NoiseFunction2.java | 27 ++++++++++++++++- src/test/java/NoiseTest.java | 29 +++++++++++++++---- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/dfsek/terra/math/NoiseFunction2.java b/src/main/java/com/dfsek/terra/math/NoiseFunction2.java index 898b760c2..ac3ab8d87 100644 --- a/src/main/java/com/dfsek/terra/math/NoiseFunction2.java +++ b/src/main/java/com/dfsek/terra/math/NoiseFunction2.java @@ -4,10 +4,12 @@ import com.dfsek.terra.generation.config.NoiseBuilder; import org.polydev.gaea.math.FastNoiseLite; import parsii.eval.Expression; +import java.util.HashMap; import java.util.List; public class NoiseFunction2 implements NoiseFunction { private final FastNoiseLite gen; + private final Cache cache = new Cache(); public NoiseFunction2(long seed, NoiseBuilder builder) { this.gen = builder.build((int) seed); @@ -20,11 +22,34 @@ public class NoiseFunction2 implements NoiseFunction { @Override public double eval(List list) { - return gen.getNoise(list.get(0).evaluate(), list.get(1).evaluate()); + return cache.get(gen, (int) list.get(0).evaluate(), (int) list.get(1).evaluate()); + } + + /** + * Evaluate without cache. For testing. + * + * @param list Parameters. + * @return Result. + */ + public double evalNoCache(List list) { + return gen.getNoise((int) list.get(0).evaluate(), (int) list.get(1).evaluate()); } @Override public boolean isNaturalFunction() { return true; } + + private static class Cache { + private final HashMap map = new HashMap<>(); + + public double get(FastNoiseLite noise, int x, int z) { + long key = (((long) x) << 32) + z; + + return map.computeIfAbsent(key, k -> { + if(map.size() > 512) map.clear(); + return noise.getNoise(x, z); + }); + } + } } diff --git a/src/test/java/NoiseTest.java b/src/test/java/NoiseTest.java index b11cacc94..7be68ad2d 100644 --- a/src/test/java/NoiseTest.java +++ b/src/test/java/NoiseTest.java @@ -9,13 +9,32 @@ public class NoiseTest { @Test public void noise() { NoiseFunction2 noiseFunction = new NoiseFunction2(12345, new NoiseBuilder()); - + System.out.println("Cache:"); for(int i = 0; i < 10; i++) { long l = System.nanoTime(); - for(int j = 0; j < 1000000; j++) { - noiseFunction.eval(Arrays.asList(get(j), get(i))); - noiseFunction.eval(Arrays.asList(get(j), get(i))); - noiseFunction.eval(Arrays.asList(get(j), get(i))); + for(int j = 0; j < 20000; j++) { + for(int x = 0; x < 4; x++) { + for(int y = 0; y < 64; y++) { + for(int z = 0; z < 4; z++) { + noiseFunction.eval(Arrays.asList(get(j * 16 + (x * 4)), get(i * 16 + (z * 4)))); + } + } + } + } + double n = System.nanoTime() - l; + System.out.println(n / 1000000 + "ms"); + } + System.out.println("No Cache:"); + for(int i = 0; i < 10; i++) { + long l = System.nanoTime(); + for(int j = 0; j < 20000; j++) { + for(int x = 0; x < 4; x++) { + for(int y = 0; y < 64; y++) { + for(int z = 0; z < 4; z++) { + noiseFunction.evalNoCache(Arrays.asList(get(j * 16 + (x * 4)), get(i * 16 + (z * 4)))); + } + } + } } double n = System.nanoTime() - l; System.out.println(n / 1000000 + "ms");