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 The reasoning for reusing it in ChunkRegionLoader is because ThreadLocal lookups are fairly expensive, and if we put it in DataPaletteBlock the ThreadLocal lookup would happen 18 times. Airplane Copyright (C) 2020 Technove LLC This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . 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 c9e942669458668a184aaec3bc0a5509dd6ab5f0..178e56ffc87ea2beb4d84d1f278f4acf90102379 100644 --- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java +++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java @@ -263,13 +263,17 @@ public class PalettedContainer implements PaletteResize { } + // Airplane 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 // Airplane 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]; // Airplane 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 7921ee2786d0d6a60d43786b20efc03a0f9178e3..9ea4229f58679c6c833762fc6a50471445ff0b9d 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 @@ -500,6 +500,7 @@ public class ChunkSerializer { return new AsyncSaveData(blockLight, skyLight, blockTickListSerialized, fluidTickListSerialized, blockEntitiesSerialized, world.getGameTime()); } + private static final ThreadLocal paletteArray = ThreadLocal.withInitial(() -> new int[4096]); // Airplane public static CompoundTag write(ServerLevel world, ChunkAccess chunk) { return saveChunk(world, chunk, null); } @@ -533,6 +534,7 @@ public class ChunkSerializer { ThreadedLevelLightEngine lightenginethreaded = world.getChunkSource().getLightEngine(); boolean flag = chunk.isLightCorrect(); + int[] is = paletteArray.get(); // Airplane - 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) -> { @@ -547,7 +549,7 @@ 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); // Airplane - reuse array } // Paper start - replace light engine