some more optimizations

This commit is contained in:
Julian Krings 2024-12-26 17:54:02 +01:00
parent 97c7ac0528
commit 5b60b655ed
No known key found for this signature in database
GPG Key ID: 208C6E08C3B718D2
6 changed files with 85 additions and 123 deletions

View File

@ -21,21 +21,12 @@ package com.volmit.iris.core.commands;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.ServerConfigurator; import com.volmit.iris.core.ServerConfigurator;
import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.core.nms.INMS;
import com.volmit.iris.core.nms.datapack.DataVersion; import com.volmit.iris.core.nms.datapack.DataVersion;
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
import com.volmit.iris.core.pregenerator.ChunkUpdater;
import com.volmit.iris.core.service.IrisEngineSVC; import com.volmit.iris.core.service.IrisEngineSVC;
import com.volmit.iris.core.tools.IrisConverter;
import com.volmit.iris.core.tools.IrisPackBenchmarking; import com.volmit.iris.core.tools.IrisPackBenchmarking;
import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.core.tools.IrisToolbelt;
import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.mantle.components.MantleObjectComponent;
import com.volmit.iris.engine.object.IrisBiome;
import com.volmit.iris.engine.object.IrisCave;
import com.volmit.iris.engine.object.IrisDimension; import com.volmit.iris.engine.object.IrisDimension;
import com.volmit.iris.engine.object.IrisEntity;
import com.volmit.iris.util.data.Dimension;
import com.volmit.iris.util.decree.DecreeExecutor; import com.volmit.iris.util.decree.DecreeExecutor;
import com.volmit.iris.util.decree.DecreeOrigin; import com.volmit.iris.util.decree.DecreeOrigin;
import com.volmit.iris.util.decree.annotations.Decree; import com.volmit.iris.util.decree.annotations.Decree;
@ -45,13 +36,10 @@ import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.io.CountingDataInputStream; import com.volmit.iris.util.io.CountingDataInputStream;
import com.volmit.iris.util.io.IO; import com.volmit.iris.util.io.IO;
import com.volmit.iris.util.mantle.TectonicPlate; import com.volmit.iris.util.mantle.TectonicPlate;
import com.volmit.iris.util.math.Spiraler;
import com.volmit.iris.util.math.Vector3d;
import com.volmit.iris.util.nbt.mca.MCAFile; import com.volmit.iris.util.nbt.mca.MCAFile;
import com.volmit.iris.util.nbt.mca.MCAUtil; import com.volmit.iris.util.nbt.mca.MCAUtil;
import com.volmit.iris.util.parallel.MultiBurst; import com.volmit.iris.util.parallel.MultiBurst;
import com.volmit.iris.util.plugin.VolmitSender; import com.volmit.iris.util.plugin.VolmitSender;
import io.lumine.mythic.bukkit.adapters.BukkitEntity;
import net.jpountz.lz4.LZ4BlockInputStream; import net.jpountz.lz4.LZ4BlockInputStream;
import net.jpountz.lz4.LZ4BlockOutputStream; import net.jpountz.lz4.LZ4BlockOutputStream;
import net.jpountz.lz4.LZ4FrameInputStream; import net.jpountz.lz4.LZ4FrameInputStream;
@ -59,10 +47,7 @@ import net.jpountz.lz4.LZ4FrameOutputStream;
import org.apache.commons.lang.RandomStringUtils; import org.apache.commons.lang.RandomStringUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.EntityType;
import java.io.*; import java.io.*;
import java.net.InetAddress; import java.net.InetAddress;
@ -153,12 +138,14 @@ public class CommandDeveloper implements DecreeExecutor {
@Decree(description = "Test") @Decree(description = "Test")
public void packBenchmark( public void packBenchmark(
@Param(description = "The pack to bench", aliases = {"pack"}) @Param(description = "The pack to bench", aliases = {"pack"}, defaultValue = "overworld")
IrisDimension dimension IrisDimension dimension,
@Param(description = "Radius in regions", defaultValue = "5")
int radius,
@Param(description = "Open GUI while benchmarking", defaultValue = "false")
boolean gui
) { ) {
Iris.info("test"); new IrisPackBenchmarking(dimension, radius, gui);
IrisPackBenchmarking benchmark = new IrisPackBenchmarking(dimension, 1);
} }
@Decree(description = "Upgrade to another Minecraft version") @Decree(description = "Upgrade to another Minecraft version")

View File

@ -22,7 +22,6 @@ import com.volmit.iris.Iris;
import com.volmit.iris.core.pregenerator.PregenListener; import com.volmit.iris.core.pregenerator.PregenListener;
import com.volmit.iris.core.pregenerator.PregeneratorMethod; import com.volmit.iris.core.pregenerator.PregeneratorMethod;
import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.core.tools.IrisToolbelt;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.mantle.Mantle; import com.volmit.iris.util.mantle.Mantle;
import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.M;
@ -34,12 +33,12 @@ import org.bukkit.World;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Future; import java.util.concurrent.Semaphore;
public class AsyncPregenMethod implements PregeneratorMethod { public class AsyncPregenMethod implements PregeneratorMethod {
private final World world; private final World world;
private final MultiBurst burst; private final MultiBurst burst;
private final KList<Future<?>> future; private final Semaphore semaphore;
private final Map<Chunk, Long> lastUse; private final Map<Chunk, Long> lastUse;
public AsyncPregenMethod(World world, int threads) { public AsyncPregenMethod(World world, int threads) {
@ -49,7 +48,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
this.world = world; this.world = world;
burst = new MultiBurst("Iris Async Pregen", Thread.MIN_PRIORITY); burst = new MultiBurst("Iris Async Pregen", Thread.MIN_PRIORITY);
future = new KList<>(256); semaphore = new Semaphore(256);
this.lastUse = new KMap<>(); this.lastUse = new KMap<>();
} }
@ -63,7 +62,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
for (Chunk i : new ArrayList<>(lastUse.keySet())) { for (Chunk i : new ArrayList<>(lastUse.keySet())) {
Long lastUseTime = lastUse.get(i); Long lastUseTime = lastUse.get(i);
if (lastUseTime != null && M.ms() - lastUseTime >= 10000) { if (!i.isLoaded() || (lastUseTime != null && M.ms() - lastUseTime >= 10000)) {
i.unload(); i.unload();
lastUse.remove(i); lastUse.remove(i);
} }
@ -85,37 +84,8 @@ public class AsyncPregenMethod implements PregeneratorMethod {
} catch (InterruptedException ignored) { } catch (InterruptedException ignored) {
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
} } finally {
} semaphore.release();
private void waitForChunksPartial(int maxWaiting) {
while (future.size() > maxWaiting) {
try {
Future<?> i = future.remove(0);
if (i == null) {
continue;
}
i.get();
} catch (Throwable e) {
e.printStackTrace();
}
}
}
private void waitForChunks() {
for (Future<?> i : future.copy()) {
if (i == null) {
continue;
}
try {
i.get();
future.remove(i);
} catch (Throwable e) {
e.printStackTrace();
}
} }
} }
@ -131,14 +101,13 @@ public class AsyncPregenMethod implements PregeneratorMethod {
@Override @Override
public void close() { public void close() {
waitForChunks(); semaphore.acquireUninterruptibly(256);
unloadAndSaveAllChunks(); unloadAndSaveAllChunks();
burst.close(); burst.close();
} }
@Override @Override
public void save() { public void save() {
waitForChunksPartial(256);
unloadAndSaveAllChunks(); unloadAndSaveAllChunks();
} }
@ -155,10 +124,12 @@ public class AsyncPregenMethod implements PregeneratorMethod {
@Override @Override
public void generateChunk(int x, int z, PregenListener listener) { public void generateChunk(int x, int z, PregenListener listener) {
listener.onChunkGenerating(x, z); listener.onChunkGenerating(x, z);
if (future.size() > 256) { try {
waitForChunksPartial(256); semaphore.acquire();
} catch (InterruptedException e) {
return;
} }
future.add(burst.complete(() -> completeChunk(x, z, listener))); burst.complete(() -> completeChunk(x, z, listener));
} }
@Override @Override

View File

@ -24,10 +24,8 @@ import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.ServerConfigurator; import com.volmit.iris.core.ServerConfigurator;
import com.volmit.iris.core.pregenerator.PregenTask; import com.volmit.iris.core.pregenerator.PregenTask;
import com.volmit.iris.core.service.StudioSVC; import com.volmit.iris.core.service.StudioSVC;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.object.IrisDimension; import com.volmit.iris.engine.object.IrisDimension;
import com.volmit.iris.engine.platform.PlatformChunkGenerator; import com.volmit.iris.engine.platform.PlatformChunkGenerator;
import com.volmit.iris.core.safeguard.UtilsSFG;
import com.volmit.iris.util.exceptions.IrisException; import com.volmit.iris.util.exceptions.IrisException;
import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.C;
import com.volmit.iris.util.format.Form; import com.volmit.iris.util.format.Form;
@ -46,7 +44,6 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier; import java.util.function.Supplier;
import static com.volmit.iris.core.safeguard.IrisSafeguard.unstablemode;
/** /**
* Makes it a lot easier to setup an engine, world, studio or whatever * Makes it a lot easier to setup an engine, world, studio or whatever
@ -126,14 +123,11 @@ public class IrisCreator {
if (sender == null) if (sender == null)
sender = Iris.getSender(); sender = Iris.getSender();
if (!studio()) { if (!studio() || benchmark) {
Iris.service(StudioSVC.class).installIntoWorld(sender, d.getLoadKey(), new File(Bukkit.getWorldContainer(), name()));
}
if (benchmark) {
Iris.service(StudioSVC.class).installIntoWorld(sender, d.getLoadKey(), new File(Bukkit.getWorldContainer(), name())); Iris.service(StudioSVC.class).installIntoWorld(sender, d.getLoadKey(), new File(Bukkit.getWorldContainer(), name()));
} }
PlatformChunkGenerator access = null; PlatformChunkGenerator access;
AtomicReference<World> world = new AtomicReference<>(); AtomicReference<World> world = new AtomicReference<>();
AtomicDouble pp = new AtomicDouble(0); AtomicDouble pp = new AtomicDouble(0);
O<Boolean> done = new O<>(); O<Boolean> done = new O<>();

View File

@ -9,8 +9,6 @@ import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.exceptions.IrisException; import com.volmit.iris.util.exceptions.IrisException;
import com.volmit.iris.util.format.Form; import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.math.Position2;
import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.PrecisionStopwatch; import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import lombok.Getter; import lombok.Getter;
@ -27,29 +25,29 @@ import java.nio.file.attribute.BasicFileAttributes;
import java.time.Clock; import java.time.Clock;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Collections; import java.util.Collections;
import java.util.concurrent.*;
public class IrisPackBenchmarking { public class IrisPackBenchmarking {
@Getter @Getter
public static IrisPackBenchmarking instance; public static IrisPackBenchmarking instance;
public static boolean benchmarkInProgress = false; public static boolean benchmarkInProgress = false;
private IrisDimension IrisDimension; private final PrecisionStopwatch stopwatch = new PrecisionStopwatch();
private int radius; private final IrisDimension dimension;
private boolean finished = false; private final int radius;
PrecisionStopwatch stopwatch; private final boolean gui;
public IrisPackBenchmarking(IrisDimension dimension, int r) { public IrisPackBenchmarking(IrisDimension dimension, int radius, boolean gui) {
instance = this; instance = this;
this.IrisDimension = dimension; this.dimension = dimension;
this.radius = r; this.radius = radius;
this.gui = gui;
runBenchmark(); runBenchmark();
} }
private void runBenchmark() { private void runBenchmark() {
this.stopwatch = new PrecisionStopwatch(); Thread.ofVirtual()
ExecutorService service = Executors.newSingleThreadExecutor(); .name("PackBenchmarking")
service.submit(() -> { .start(() -> {
Iris.info("Setting up benchmark environment "); Iris.info("Setting up benchmark environment ");
benchmarkInProgress = true; benchmarkInProgress = true;
File file = new File("benchmark"); File file = new File("benchmark");
@ -88,13 +86,13 @@ public class IrisPackBenchmarking {
File profilers = new File("plugins" + File.separator + "Iris" + File.separator + "packbenchmarks"); File profilers = new File("plugins" + File.separator + "Iris" + File.separator + "packbenchmarks");
profilers.mkdir(); profilers.mkdir();
File results = new File("plugins " + File.separator + "Iris", IrisDimension.getName() + LocalDateTime.now(Clock.systemDefaultZone()) + ".txt"); File results = new File(profilers, dimension.getName() + " " + LocalDateTime.now(Clock.systemDefaultZone()).toString().replace(':', '-') + ".txt");
results.createNewFile(); results.getParentFile().mkdirs();
KMap<String, Double> metrics = engine.getMetrics().pull(); KMap<String, Double> metrics = engine.getMetrics().pull();
try (FileWriter writer = new FileWriter(results)) { try (FileWriter writer = new FileWriter(results)) {
writer.write("-----------------\n"); writer.write("-----------------\n");
writer.write("Results:\n"); writer.write("Results:\n");
writer.write("Dimension: " + IrisDimension.getName() + "\n"); writer.write("Dimension: " + dimension.getName() + "\n");
writer.write("- Date of Benchmark: " + LocalDateTime.now(Clock.systemDefaultZone()) + "\n"); writer.write("- Date of Benchmark: " + LocalDateTime.now(Clock.systemDefaultZone()) + "\n");
writer.write("\n"); writer.write("\n");
writer.write("Metrics"); writer.write("Metrics");
@ -116,17 +114,24 @@ public class IrisPackBenchmarking {
e.printStackTrace(); e.printStackTrace();
} }
Bukkit.getServer().unloadWorld("benchmark", true); J.s(() -> {
var world = Bukkit.getWorld("benchmark");
if (world == null) return;
IrisToolbelt.evacuate(world);
Bukkit.unloadWorld(world, true);
});
stopwatch.end(); stopwatch.end();
} catch (Exception e) { } catch (Exception e) {
Iris.error("Something has gone wrong!"); Iris.error("Something has gone wrong!");
e.printStackTrace(); e.printStackTrace();
} }
} }
private void createBenchmark(){
private void createBenchmark() {
try { try {
IrisToolbelt.createWorld() IrisToolbelt.createWorld()
.dimension(IrisDimension.getName()) .dimension(dimension.getLoadKey())
.name("benchmark") .name("benchmark")
.seed(1337) .seed(1337)
.studio(false) .studio(false)
@ -137,15 +142,12 @@ public class IrisPackBenchmarking {
} }
} }
private void startBenchmark(){ private void startBenchmark() {
int x = 0;
int z = 0;
IrisToolbelt.pregenerate(PregenTask IrisToolbelt.pregenerate(PregenTask
.builder() .builder()
.gui(false) .gui(gui)
.center(new Position2(x, z)) .width(radius)
.width(5) .height(radius)
.height(5)
.build(), Bukkit.getWorld("benchmark") .build(), Bukkit.getWorld("benchmark")
); );
} }
@ -179,7 +181,7 @@ public class IrisPackBenchmarking {
private boolean deleteDirectory(Path dir) { private boolean deleteDirectory(Path dir) {
try { try {
Files.walkFileTree(dir, new SimpleFileVisitor<Path>() { Files.walkFileTree(dir, new SimpleFileVisitor<>() {
@Override @Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file); Files.delete(file);

View File

@ -29,6 +29,7 @@ import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.collection.KSet;
import com.volmit.iris.util.context.IrisContext; import com.volmit.iris.util.context.IrisContext;
import com.volmit.iris.util.data.DataProvider; import com.volmit.iris.util.data.DataProvider;
import com.volmit.iris.util.interpolation.IrisInterpolation.NoiseKey;
import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.M;
import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.noise.CNG; import com.volmit.iris.util.noise.CNG;
@ -292,9 +293,11 @@ public class IrisComplex implements DataProvider {
return 0; return 0;
} }
KMap<NoiseKey, IrisBiome> cache = new KMap<>();
double hi = interpolator.interpolate(x, z, (xx, zz) -> { double hi = interpolator.interpolate(x, z, (xx, zz) -> {
try { try {
IrisBiome bx = baseBiomeStream.get(xx, zz); IrisBiome bx = baseBiomeStream.get(xx, zz);
cache.put(new NoiseKey(xx, zz), bx);
double b = 0; double b = 0;
for (IrisGenerator gen : generators) { for (IrisGenerator gen : generators) {
@ -313,7 +316,11 @@ public class IrisComplex implements DataProvider {
double lo = interpolator.interpolate(x, z, (xx, zz) -> { double lo = interpolator.interpolate(x, z, (xx, zz) -> {
try { try {
IrisBiome bx = baseBiomeStream.get(xx, zz); IrisBiome bx = cache.get(new NoiseKey(xx, zz));
if (bx == null) {
bx = baseBiomeStream.get(xx, zz);
cache.put(new NoiseKey(xx, zz), bx);
}
double b = 0; double b = 0;
for (IrisGenerator gen : generators) { for (IrisGenerator gen : generators) {

View File

@ -997,11 +997,9 @@ public class IrisInterpolation {
return getNoise3D(method, x, y, z, rad, rad, rad, n); return getNoise3D(method, x, y, z, rad, rad, rad, n);
} }
private record Key(double x, double z) {}
public static double getNoise(InterpolationMethod method, int x, int z, double h, NoiseProvider noise) { public static double getNoise(InterpolationMethod method, int x, int z, double h, NoiseProvider noise) {
HashMap<Key, Double> cache = new HashMap<>(64); HashMap<NoiseKey, Double> cache = new HashMap<>(64);
NoiseProvider n = (x1, z1) -> cache.computeIfAbsent(new Key(x1, z1), k -> noise.noise(k.x, k.z)); NoiseProvider n = (x1, z1) -> cache.computeIfAbsent(new NoiseKey(x1, z1), k -> noise.noise(k.x, k.z));
if (method.equals(InterpolationMethod.BILINEAR)) { if (method.equals(InterpolationMethod.BILINEAR)) {
return getBilinearNoise(x, z, h, n); return getBilinearNoise(x, z, h, n);
@ -1063,4 +1061,7 @@ public class IrisInterpolation {
public static double rangeScale(double amin, double amax, double bmin, double bmax, double b) { public static double rangeScale(double amin, double amax, double bmin, double bmax, double b) {
return amin + ((amax - amin) * ((b - bmin) / (bmax - bmin))); return amin + ((amax - amin) * ((b - bmin) / (bmax - bmin)));
} }
public record NoiseKey(double x, double z) {
}
} }