Implement NoiseFunction2 cache

This commit is contained in:
dfsek 2020-11-21 16:14:09 -07:00
parent 4174dc9ab0
commit 1f8d9a710f
2 changed files with 50 additions and 6 deletions

View File

@ -4,10 +4,12 @@ import com.dfsek.terra.generation.config.NoiseBuilder;
import org.polydev.gaea.math.FastNoiseLite; import org.polydev.gaea.math.FastNoiseLite;
import parsii.eval.Expression; import parsii.eval.Expression;
import java.util.HashMap;
import java.util.List; import java.util.List;
public class NoiseFunction2 implements NoiseFunction { public class NoiseFunction2 implements NoiseFunction {
private final FastNoiseLite gen; private final FastNoiseLite gen;
private final Cache cache = new Cache();
public NoiseFunction2(long seed, NoiseBuilder builder) { public NoiseFunction2(long seed, NoiseBuilder builder) {
this.gen = builder.build((int) seed); this.gen = builder.build((int) seed);
@ -20,11 +22,34 @@ public class NoiseFunction2 implements NoiseFunction {
@Override @Override
public double eval(List<Expression> list) { public double eval(List<Expression> 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<Expression> list) {
return gen.getNoise((int) list.get(0).evaluate(), (int) list.get(1).evaluate());
} }
@Override @Override
public boolean isNaturalFunction() { public boolean isNaturalFunction() {
return true; return true;
} }
private static class Cache {
private final HashMap<Long, Double> 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);
});
}
}
} }

View File

@ -9,13 +9,32 @@ public class NoiseTest {
@Test @Test
public void noise() { public void noise() {
NoiseFunction2 noiseFunction = new NoiseFunction2(12345, new NoiseBuilder()); NoiseFunction2 noiseFunction = new NoiseFunction2(12345, new NoiseBuilder());
System.out.println("Cache:");
for(int i = 0; i < 10; i++) { for(int i = 0; i < 10; i++) {
long l = System.nanoTime(); long l = System.nanoTime();
for(int j = 0; j < 1000000; j++) { for(int j = 0; j < 20000; j++) {
noiseFunction.eval(Arrays.asList(get(j), get(i))); for(int x = 0; x < 4; x++) {
noiseFunction.eval(Arrays.asList(get(j), get(i))); for(int y = 0; y < 64; y++) {
noiseFunction.eval(Arrays.asList(get(j), get(i))); 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; double n = System.nanoTime() - l;
System.out.println(n / 1000000 + "ms"); System.out.println(n / 1000000 + "ms");