From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paul Sauve Date: Thu, 4 Feb 2021 23:28:46 -0600 Subject: [PATCH] Cache palette array Instead of allocating the 4KB for every chunk section, cache it locally and reuse it for other chunk sections to save on allocations. These allocations add up very quickly when saving chunks frequently. diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java +++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java @@ -0,0 +0,0 @@ public class PalettedContainer implements PaletteResize { } + // Paper start - allow reusing int array public synchronized void write(CompoundTag nbt, String paletteKey, String dataKey) { // Paper - synchronize + this.write(nbt, paletteKey, dataKey, new int[4096]); + } + public synchronized void write(CompoundTag nbt, String paletteKey, String dataKey, int[] is) { // Paper - synchronize // Paper end try { this.acquire(); HashMapPalette hashMapPalette = new HashMapPalette<>(this.registry, this.bits, this.dummyPaletteResize, this.reader, this.writer); T object = this.defaultValue; int i = hashMapPalette.idFor(this.defaultValue); - int[] is = new int[4096]; + //int[] is = new int[4096]; // Paper - will now be pulled from ThreadLocal for(int j = 0; j < 4096; ++j) { T object2 = this.get(j); diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java @@ -0,0 +0,0 @@ public class ChunkSerializer { return new AsyncSaveData(blockLight, skyLight, blockTickListSerialized, fluidTickListSerialized, blockEntitiesSerialized, world.getGameTime()); } + private static final ThreadLocal PALETTE_ARRAY = ThreadLocal.withInitial(() -> new int[4096]); // Paper - maintain a per-thread cache for saving palettes public static CompoundTag write(ServerLevel world, ChunkAccess chunk) { return saveChunk(world, chunk, null); } @@ -0,0 +0,0 @@ public class ChunkSerializer { ThreadedLevelLightEngine lightenginethreaded = world.getChunkSource().getLightEngine(); boolean flag = chunk.isLightCorrect(); + int[] is = PALETTE_ARRAY.get(); // Paper - use cached for (int i = lightenginethreaded.getMinLightSection(); i < lightenginethreaded.getMaxLightSection(); ++i) { int finalI = i; // CraftBukkit - decompile errors LevelChunkSection chunksection = (LevelChunkSection) Arrays.stream(achunksection).filter((chunksection1) -> { @@ -0,0 +0,0 @@ public class ChunkSerializer { nbttagcompound2.putByte("Y", (byte) (i & 255)); if (chunksection != LevelChunk.EMPTY_SECTION) { - chunksection.getStates().write(nbttagcompound2, "Palette", "BlockStates"); + chunksection.getStates().write(nbttagcompound2, "Palette", "BlockStates", is); // Paper - reuse array } // Paper start - replace light engine