From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Derek Lee Date: Sat, 18 Mar 2023 18:54:57 -0700 Subject: [PATCH] Add Lithium optimizations diff --git a/src/main/java/net/minecraft/core/AxisCycle.java b/src/main/java/net/minecraft/core/AxisCycle.java index b5d8a60dc78a76c0a55bfc30cc49d26857bd914a..e181a36f77dd27912faf0b3c00ec49b79dce19d5 100644 --- a/src/main/java/net/minecraft/core/AxisCycle.java +++ b/src/main/java/net/minecraft/core/AxisCycle.java @@ -35,7 +35,13 @@ public enum AxisCycle { @Override public Direction.Axis cycle(Direction.Axis axis) { - return AXIS_VALUES[Math.floorMod(axis.ordinal() + 1, 3)]; + // Lithium start - avoid modulo/array operations + return switch (axis) { + case X -> Direction.Axis.Y; + case Y -> Direction.Axis.Z; + case Z -> Direction.Axis.X; + }; + // Lithium end } @Override @@ -56,7 +62,13 @@ public enum AxisCycle { @Override public Direction.Axis cycle(Direction.Axis axis) { - return AXIS_VALUES[Math.floorMod(axis.ordinal() - 1, 3)]; + // Lithium start - avoid modulo/array operations + return switch (axis) { + case X -> Direction.Axis.Z; + case Y -> Direction.Axis.X; + case Z -> Direction.Axis.Y; + }; + // Lithium end } @Override diff --git a/src/main/java/net/minecraft/core/Direction.java b/src/main/java/net/minecraft/core/Direction.java index d0a8092bf57a29ab7c00ec0ddf52a9fdb2a33267..6efea274842e3813282508a23c46fe9224dc0960 100644 --- a/src/main/java/net/minecraft/core/Direction.java +++ b/src/main/java/net/minecraft/core/Direction.java @@ -182,7 +182,7 @@ public enum Direction implements StringRepresentable { } public Direction getOpposite() { - return from3DDataValue(this.oppositeIndex); + return VALUES[this.oppositeIndex]; // Lithium - avoid modulo/abs operations } public Direction getClockWise(Direction.Axis axis) { diff --git a/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java b/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java index 50a9f33aa31e9273c7c52d4bb2b02f0f884f7ba5..111a6054fe60313dcc5d5122094b6c3f5fe27e06 100644 --- a/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java +++ b/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java @@ -13,7 +13,7 @@ import java.util.Map; import java.util.stream.Collectors; public class ClassInstanceMultiMap extends AbstractCollection { - private final Map, List> byClass = Maps.newHashMap(); + private final Map, List> byClass = new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>(); // Lithium - use faster collection private final Class baseClass; private final List allInstances = Lists.newArrayList(); @@ -55,15 +55,24 @@ public class ClassInstanceMultiMap extends AbstractCollection { } public Collection find(Class type) { - if (!this.baseClass.isAssignableFrom(type)) { - throw new IllegalArgumentException("Don't know how to search for " + type); - } else { - List list = this.byClass.computeIfAbsent(type, (typeClass) -> { - return this.allInstances.stream().filter(typeClass::isInstance).collect(Collectors.toList()); - }); - return Collections.unmodifiableCollection(list); + // Lithium start - improve performance when entities are being queried in the world + Collection collection = this.byClass.get(type); + if (collection == null) { + collection = this.create(type); } + return (Collection) Collections.unmodifiableCollection(collection); } + private Collection create(Class type) { + final List list = new java.util.ArrayList<>(); + for (T element : this.allInstances) { + if (type.isInstance(element)) { + list.add(element); + } + } + this.byClass.put(type, list); + return list; + } + // Lithium end @Override public Iterator iterator() { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java index f78a91deb3c9080ed1c35588f081f13836e8c727..a0cb2269693bbe2e35a25cfb8c1072b33e216c0f 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -572,7 +572,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { this.random = SHARED_RANDOM; // Paper this.remainingFireTicks = -this.getFireImmuneTicks(); this.fluidHeight = new Object2DoubleArrayMap(2); - this.fluidOnEyes = new HashSet(); + this.fluidOnEyes = new it.unimi.dsi.fastutil.objects.ReferenceArraySet<>(); // Lithium - use faster collection this.firstTick = true; this.levelCallback = EntityInLevelCallback.NULL; this.packetPositionCodec = new VecDeltaCodec(); @@ -1866,7 +1866,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { private void updateFluidOnEyes() { this.wasEyeInWater = this.isEyeInFluid(FluidTags.WATER); - this.fluidOnEyes.clear(); + if (!this.fluidOnEyes.isEmpty()) this.fluidOnEyes.clear(); // Lithium - use faster collection double d0 = this.getEyeY() - 0.1111111119389534D; Entity entity = this.getVehicle(); diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java index dd1102d5291ef6f18e82400a6d8a0a376cc071e9..3d7f84b8b50e34d619993adafac4b1399a4e2399 100644 --- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java +++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java @@ -20,8 +20,8 @@ import org.slf4j.Logger; public class AttributeMap { private static final Logger LOGGER = LogUtils.getLogger(); - private final Map attributes = Maps.newHashMap(); - private final Set dirtyAttributes = Sets.newHashSet(); + private final Map attributes = new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>(); // Lithium - use faster collection + private final Set dirtyAttributes = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Lithium - use faster collection private final AttributeSupplier supplier; public AttributeMap(AttributeSupplier defaultAttributes) { diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java index 6d6cdb8e3f627c6e7ee291d9bceb0754088a4c8f..3077cfc9d106a7208a3ecd037a99d3458b6e0b14 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java @@ -28,7 +28,7 @@ public class GoalSelector { } }; private final Map lockedFlags = new EnumMap<>(Goal.Flag.class); - private final Set availableGoals = Sets.newLinkedHashSet(); + private final Set availableGoals = new it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet<>(); // Lithium - use faster collection private final Supplier profiler; private final EnumSet disabledFlags = EnumSet.noneOf(Goal.Flag.class); // Paper unused, but dummy to prevent plugins from crashing as hard. Theyll need to support paper in a special case if this is super important, but really doesn't seem like it would be. private final com.destroystokyo.paper.util.set.OptimizedSmallEnumSet goalTypes = new com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector diff --git a/src/main/java/net/minecraft/world/level/biome/MobSpawnSettings.java b/src/main/java/net/minecraft/world/level/biome/MobSpawnSettings.java index 9e2f7fc64b284efd6388be35f250642c47e7603b..902d1de8cba7c01d0c95ca3ae92a917b81356042 100644 --- a/src/main/java/net/minecraft/world/level/biome/MobSpawnSettings.java +++ b/src/main/java/net/minecraft/world/level/biome/MobSpawnSettings.java @@ -43,7 +43,7 @@ public class MobSpawnSettings { MobSpawnSettings(float creatureSpawnProbability, Map> spawners, Map, MobSpawnSettings.MobSpawnCost> spawnCosts) { this.creatureGenerationProbability = creatureSpawnProbability; - this.spawners = ImmutableMap.copyOf(spawners); + this.spawners = Maps.newEnumMap(spawners); // Lithium - use faster collection this.mobSpawnCosts = ImmutableMap.copyOf(spawnCosts); } diff --git a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java index 10d3912ef043eefdf89105332e29b0d2bf4a5539..0d1a76b7a53a5ea07ac374bb1881f55b087db184 100644 --- a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java @@ -415,7 +415,7 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { @Override public int[] getSlotsForFace(Direction side) { - return side == Direction.DOWN ? new int[]{0} : new int[0]; + return side == Direction.DOWN ? SLOTS_FOR_SINGLE_SLOT : SLOTS_FOR_EMPTY; // Lithium - avoid allocations } @Override @@ -464,7 +464,7 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { @Override public int[] getSlotsForFace(Direction side) { - return side == Direction.UP ? new int[]{0} : new int[0]; + return side == Direction.UP ? SLOTS_FOR_SINGLE_SLOT : SLOTS_FOR_EMPTY; // Lithium - avoid allocations } @Override @@ -506,7 +506,7 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { @Override public int[] getSlotsForFace(Direction side) { - return new int[0]; + return SLOTS_FOR_EMPTY; // Lithium - avoid allocations } @Override @@ -519,4 +519,8 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { return false; } } + // Lithium start - avoid allocations + private static final int[] SLOTS_FOR_SINGLE_SLOT = new int[] { 0 }; + private static final int[] SLOTS_FOR_EMPTY = new int[0]; + // Lithium end } diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java index 94ab7137530995f3ed5d8103729af9c3d6e94be3..2ea04071a1e213dd9a7536303b24d395dda4539b 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -95,7 +95,7 @@ public class LevelChunk extends ChunkAccess { this.setBlockNibbles(ca.spottedleaf.starlight.common.light.StarLightEngine.getFilledEmptyLight(world)); this.setSkyNibbles(ca.spottedleaf.starlight.common.light.StarLightEngine.getFilledEmptyLight(world)); // Paper end - rewrite light engine - this.tickersInLevel = Maps.newHashMap(); + this.tickersInLevel = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(); // Lithium - use faster collection this.level = (ServerLevel) world; // CraftBukkit - type this.gameEventListenerRegistrySections = new Int2ObjectOpenHashMap(); Heightmap.Types[] aheightmap_type = Heightmap.Types.values();