From 68e76b43b8e4f215222add61ab70b35448f05191 Mon Sep 17 00:00:00 2001 From: miclebrick Date: Thu, 23 Aug 2018 11:45:32 -0400 Subject: [PATCH] Optimize CraftBlockData Creation Avoids a hashmap lookup by cacheing a reference to the CraftBlockData and cloning it when one is needed. --- .../block/state/BlockBehaviour.java.patch | 22 ++++++++++++++++--- .../block/data/CraftBlockData.java | 10 +++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/state/BlockBehaviour.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/state/BlockBehaviour.java.patch index 8b26de6db8..1b17664e58 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/state/BlockBehaviour.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/state/BlockBehaviour.java.patch @@ -50,7 +50,23 @@ } state.spawnAfterBreak(world, pos, ItemStack.EMPTY, flag); -@@ -873,12 +887,14 @@ +@@ -851,7 +865,15 @@ + this.spawnTerrainParticles = blockbase_info.spawnTerrainParticles; + this.instrument = blockbase_info.instrument; + this.replaceable = blockbase_info.replaceable; ++ } ++ // Paper start - Perf: impl cached craft block data, lazy load to fix issue with loading at the wrong time ++ private org.bukkit.craftbukkit.block.data.CraftBlockData cachedCraftBlockData; ++ ++ public org.bukkit.craftbukkit.block.data.CraftBlockData createCraftBlockData() { ++ if (cachedCraftBlockData == null) cachedCraftBlockData = org.bukkit.craftbukkit.block.data.CraftBlockData.createData(asState()); ++ return (org.bukkit.craftbukkit.block.data.CraftBlockData) cachedCraftBlockData.clone(); + } ++ // Paper end - Perf: impl cached craft block data, lazy load to fix issue with loading at the wrong time + + private boolean calculateSolid() { + if (((Block) this.owner).properties.forceSolidOn) { +@@ -873,12 +895,14 @@ } } @@ -65,7 +81,7 @@ this.legacySolid = this.calculateSolid(); this.occlusionShape = this.canOcclude ? ((Block) this.owner).getOcclusionShape(this.asState()) : Shapes.empty(); -@@ -945,8 +961,8 @@ +@@ -945,8 +969,8 @@ return this.occlusionShape; } @@ -76,7 +92,7 @@ } public boolean useShapeForLightOcclusion() { -@@ -1125,9 +1141,15 @@ +@@ -1125,9 +1149,15 @@ } public void onPlace(Level world, BlockPos pos, BlockState state, boolean notify) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java index fc27930e4c..82816ad68d 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java @@ -579,7 +579,17 @@ public class CraftBlockData implements BlockData { return craft; } + // Paper start - optimize creating BlockData to not need a map lookup + static { + // Initialize cached data for all IBlockData instances after registration + Block.BLOCK_STATE_REGISTRY.iterator().forEachRemaining(net.minecraft.world.level.block.state.BlockState::createCraftBlockData); + } public static CraftBlockData fromData(net.minecraft.world.level.block.state.BlockState data) { + return data.createCraftBlockData(); + } + + public static CraftBlockData createData(net.minecraft.world.level.block.state.BlockState data) { + // Paper end return CraftBlockData.MAP.getOrDefault(data.getBlock().getClass(), CraftBlockData::new).apply(data); }