Added an allocaction cache for WorldSection arrays which decreased allocation rates from 10gb/s to 150mb/s

This commit is contained in:
mcrcortex
2024-02-22 11:29:53 +10:00
parent 17240e9288
commit e5c1e22bad
2 changed files with 27 additions and 2 deletions

View File

@@ -2,6 +2,9 @@ package me.cortex.voxy.common.world;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import me.cortex.voxy.common.util.VolatileHolder; import me.cortex.voxy.common.util.VolatileHolder;
import me.cortex.voxy.common.world.other.Mapper;
import java.util.Arrays;
public class ActiveSectionTracker { public class ActiveSectionTracker {
//Deserialize into the supplied section, returns true on success, false on failure //Deserialize into the supplied section, returns true on success, false on failure
@@ -60,6 +63,10 @@ public class ActiveSectionTracker {
section.release(); section.release();
return null; return null;
} }
if (status == 1) {
//We need to set the data to air as it is undefined state
Arrays.fill(section.data, Mapper.AIR);
}
return section; return section;
} else { } else {
WorldSection section = null; WorldSection section = null;

View File

@@ -1,20 +1,26 @@
package me.cortex.voxy.common.world; package me.cortex.voxy.common.world;
import java.util.ArrayDeque;
import java.util.Arrays; import java.util.Arrays;
import java.util.Deque;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
//Represents a loaded world section at a specific detail level //Represents a loaded world section at a specific detail level
// holds a 32x32x32 region of detail // holds a 32x32x32 region of detail
public final class WorldSection { public final class WorldSection {
private static final int ARRAY_REUSE_CACHE_SIZE = 256;
private static final Deque<long[]> ARRAY_REUSE_CACHE = new ArrayDeque<>(1024);
public final int lvl; public final int lvl;
public final int x; public final int x;
public final int y; public final int y;
public final int z; public final int z;
public final long key; public final long key;
long[] data; long[] data = null;
private final ActiveSectionTracker tracker; private final ActiveSectionTracker tracker;
public final AtomicBoolean inSaveQueue = new AtomicBoolean(); public final AtomicBoolean inSaveQueue = new AtomicBoolean();
@@ -29,7 +35,14 @@ public final class WorldSection {
this.key = WorldEngine.getWorldSectionId(lvl, x, y, z); this.key = WorldEngine.getWorldSectionId(lvl, x, y, z);
this.tracker = tracker; this.tracker = tracker;
this.data = new long[32*32*32]; if (!ARRAY_REUSE_CACHE.isEmpty()) {
synchronized (ARRAY_REUSE_CACHE) {
this.data = ARRAY_REUSE_CACHE.poll();
}
}
if (this.data == null) {
this.data = new long[32 * 32 * 32];
}
} }
@Override @Override
@@ -73,6 +86,11 @@ public final class WorldSection {
} }
boolean isFreed = witness == 1; boolean isFreed = witness == 1;
if (isFreed) { if (isFreed) {
if (ARRAY_REUSE_CACHE.size() < ARRAY_REUSE_CACHE_SIZE) {
synchronized (ARRAY_REUSE_CACHE) {
ARRAY_REUSE_CACHE.add(this.data);
}
}
this.data = null; this.data = null;
} }
return isFreed; return isFreed;