From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> Date: Fri, 31 Jan 2025 21:50:46 +0300 Subject: [PATCH] Misc Optimizations diff --git a/com/mojang/math/Transformation.java b/com/mojang/math/Transformation.java index 5fb382be4d86328690c49f2a5a0c3ec698a38e21..f333d9028f315e7912dd335c8158abd525c27ecd 100644 --- a/com/mojang/math/Transformation.java +++ b/com/mojang/math/Transformation.java @@ -52,6 +52,7 @@ public final class Transformation { } else { this.matrix = matrix; } + ensureDecomposed(); // DivineMC - Math Optimizations } public Transformation(@Nullable Vector3f translation, @Nullable Quaternionf leftRotation, @Nullable Vector3f scale, @Nullable Quaternionf rightRotation) { @@ -61,6 +62,7 @@ public final class Transformation { this.scale = scale != null ? scale : new Vector3f(1.0F, 1.0F, 1.0F); this.rightRotation = rightRotation != null ? rightRotation : new Quaternionf(); this.decomposed = true; + ensureDecomposed(); // DivineMC - Math Optimizations } public static Transformation identity() { diff --git a/net/minecraft/core/MappedRegistry.java b/net/minecraft/core/MappedRegistry.java index 761e583a56b1c4a605b0cbb04b61c4df60b8b9bb..c07155589ef44cbbacafe03b36d2cd4cdcba3fd2 100644 --- a/net/minecraft/core/MappedRegistry.java +++ b/net/minecraft/core/MappedRegistry.java @@ -33,10 +33,12 @@ public class MappedRegistry implements WritableRegistry { private final ResourceKey> key; private final ObjectList> byId = new ObjectArrayList<>(256); private final Reference2IntMap toId = Util.make(new Reference2IntOpenHashMap<>(2048), map -> map.defaultReturnValue(-1)); // Paper - Perf: Use bigger expected size to reduce collisions - private final Map> byLocation = new HashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions - private final Map, Holder.Reference> byKey = new HashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions - private final Map> byValue = new IdentityHashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions - private final Map, RegistrationInfo> registrationInfos = new IdentityHashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions + // DivineMC start - Some optimizations + private final Map> byLocation = new java.util.concurrent.ConcurrentHashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions + private final Map, Holder.Reference> byKey = new java.util.concurrent.ConcurrentHashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions + private final Map> byValue = Collections.synchronizedMap(new IdentityHashMap<>(2048)); // Paper - Perf: Use bigger expected size to reduce collisions + private final Map, RegistrationInfo> registrationInfos = Collections.synchronizedMap(new IdentityHashMap<>(2048)); // Paper - Perf: Use bigger expected size to reduce collisions + // DivineMC end - Some optimizations private Lifecycle registryLifecycle; private final Map, HolderSet.Named> frozenTags = new IdentityHashMap<>(); MappedRegistry.TagSet allTags = MappedRegistry.TagSet.unbound(); diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java index 00a82873d226f113278632a53c0faca420dd67d4..b28829f9f4c084a8dba35219dae9f4a9f293c416 100644 --- a/net/minecraft/network/Connection.java +++ b/net/minecraft/network/Connection.java @@ -610,13 +610,7 @@ public class Connection extends SimpleChannelInboundHandler> { if (!(this.packetListener instanceof net.minecraft.server.network.ServerLoginPacketListenerImpl loginPacketListener) || loginPacketListener.state != net.minecraft.server.network.ServerLoginPacketListenerImpl.State.VERIFYING || Connection.joinAttemptsThisTick++ < MAX_PER_TICK) { - // Paper start - detailed watchdog information - net.minecraft.network.protocol.PacketUtils.packetProcessing.push(this.packetListener); - try { tickablePacketListener.tick(); - } finally { - net.minecraft.network.protocol.PacketUtils.packetProcessing.pop(); - } // Paper end - detailed watchdog information } // Paper end - Buffer joins to world } diff --git a/net/minecraft/network/VarInt.java b/net/minecraft/network/VarInt.java index 4897ff4648083ebe737ae5b32bae344af27357e4..0d103821d7220daa5cc0d5d3231e794fca0ca055 100644 --- a/net/minecraft/network/VarInt.java +++ b/net/minecraft/network/VarInt.java @@ -52,16 +52,43 @@ public class VarInt { public static ByteBuf write(ByteBuf buffer, int value) { // Paper start - Optimize VarInts - // Peel the one and two byte count cases explicitly as they are the most common VarInt sizes - // that the proxy will write, to improve inlining. - if ((value & (0xFFFFFFFF << 7)) == 0) { - buffer.writeByte(value); - } else if ((value & (0xFFFFFFFF << 14)) == 0) { - int w = (value & 0x7F | 0x80) << 8 | (value >>> 7); - buffer.writeShort(w); - } else { - writeOld(buffer, value); + // DivineMC start - Misc optimizations + int bytesNeeded = getByteSize(value); + + switch (bytesNeeded) { + case 1: + buffer.writeByte(value); + break; + case 2: + int w2 = ((value & 0x7F) << 8) | (value >>> 7) | 0x00008000; + buffer.writeShort(w2); + break; + case 3: + int w3 = (value & 0x7F) << 16 + | (value & 0x3F80) << 1 + | (value >>> 14) + | 0x00808000; + buffer.writeMedium(w3); + break; + case 4: + int w4 = (value & 0x7F) << 24 + | ((value & 0x3F80) << 9) + | (value & 0x1FC000) >> 6 + | (value >>> 21) + | 0x80808000; + buffer.writeInt(w4); + break; + case 5: + int w5 = (value & 0x7F) << 24 + | (value & 0x3F80) << 9 + | (value & 0x1FC000) >> 6 + | ((value >>> 21) & 0x7F) + | 0x80808080; + buffer.writeInt(w5); + buffer.writeByte(value >>> 28); + break; } + // DivineMC end - Slightly optimized VarInt#write return buffer; } public static ByteBuf writeOld(ByteBuf buffer, int value) { diff --git a/net/minecraft/network/protocol/PacketUtils.java b/net/minecraft/network/protocol/PacketUtils.java index 4535858701b2bb232b9d2feb2af6551526232ddc..e65c62dbe4c1560ae153e4c4344e9194c783a2f4 100644 --- a/net/minecraft/network/protocol/PacketUtils.java +++ b/net/minecraft/network/protocol/PacketUtils.java @@ -21,8 +21,6 @@ public class PacketUtils { public static void ensureRunningOnSameThread(Packet packet, T processor, BlockableEventLoop executor) throws RunningOnDifferentThreadException { if (!executor.isSameThread()) { executor.executeIfPossible(() -> { - packetProcessing.push(processor); // Paper - detailed watchdog information - try { // Paper - detailed watchdog information if (processor instanceof net.minecraft.server.network.ServerCommonPacketListenerImpl serverCommonPacketListener && serverCommonPacketListener.processedDisconnect) return; // Paper - Don't handle sync packets for kicked players if (processor.shouldHandleMessage(packet)) { try { @@ -37,12 +35,6 @@ public class PacketUtils { } else { LOGGER.debug("Ignoring packet due to disconnection: {}", packet); } - // Paper start - detailed watchdog information - } finally { - totalMainThreadPacketsProcessed.getAndIncrement(); - packetProcessing.pop(); - } - // Paper end - detailed watchdog information }); throw RunningOnDifferentThreadException.RUNNING_ON_DIFFERENT_THREAD; } @@ -69,22 +61,4 @@ public class PacketUtils { packetListener.fillCrashReport(crashReport); } - - // Paper start - detailed watchdog information - public static final java.util.concurrent.ConcurrentLinkedDeque packetProcessing = new java.util.concurrent.ConcurrentLinkedDeque<>(); - static final java.util.concurrent.atomic.AtomicLong totalMainThreadPacketsProcessed = new java.util.concurrent.atomic.AtomicLong(); - - public static long getTotalProcessedPackets() { - return totalMainThreadPacketsProcessed.get(); - } - - public static java.util.List getCurrentPacketProcessors() { - java.util.List listeners = new java.util.ArrayList<>(4); - for (PacketListener listener : packetProcessing) { - listeners.add(listener); - } - - return listeners; - } - // Paper end - detailed watchdog information } diff --git a/net/minecraft/server/level/ChunkTrackingView.java b/net/minecraft/server/level/ChunkTrackingView.java index bee90335677f7d8b01589ce5cfd81a40fd422886..a5e488d14fd2016ee188b114d0e681562b5b09cc 100644 --- a/net/minecraft/server/level/ChunkTrackingView.java +++ b/net/minecraft/server/level/ChunkTrackingView.java @@ -73,12 +73,12 @@ public interface ChunkTrackingView { } static boolean isWithinDistance(int centerX, int centerZ, int viewDistance, int x, int z, boolean includeOuterChunksAdjacentToViewBorder) { - int i = includeOuterChunksAdjacentToViewBorder ? 2 : 1; - long l = Math.max(0, Math.abs(x - centerX) - i); - long l1 = Math.max(0, Math.abs(z - centerZ) - i); - long l2 = l * l + l1 * l1; - int i1 = viewDistance * viewDistance; - return l2 < i1; + // DivineMC start - Some optimizations + int actualViewDistance = viewDistance + (includeOuterChunksAdjacentToViewBorder ? 1 : 0); + int xDistance = Math.abs(centerX - x); + int zDistance = Math.abs(centerZ - z); + return xDistance <= actualViewDistance && zDistance <= actualViewDistance; + // DivineMC end - Some optimizations } public record Positioned(ChunkPos center, int viewDistance) implements ChunkTrackingView { diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java index 2f69b1e05ef258d6b28ee912167b8a5bb83fc703..6ed2d1aeab17941b67019d45734da46efc53ffdf 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -1312,13 +1312,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // Paper end - log detailed entity tick information public void tickNonPassenger(Entity entity) { - // Paper start - log detailed entity tick information ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread("Cannot tick an entity off-main"); - try { - if (currentlyTickingEntity.get() == null) { - currentlyTickingEntity.lazySet(entity); - } - // Paper end - log detailed entity tick information entity.setOldPosAndRot(); entity.tickCount++; entity.totalEntityAge++; // Paper - age-like counter for all entities @@ -1331,13 +1325,6 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe for (Entity entity1 : entity.getPassengers()) { this.tickPassenger(entity, entity1, isActive); // Paper - EAR 2 } - // Paper start - log detailed entity tick information - } finally { - if (currentlyTickingEntity.get() == entity) { - currentlyTickingEntity.lazySet(null); - } - } - // Paper end - log detailed entity tick information } private void tickPassenger(Entity ridingEntity, Entity passengerEntity, final boolean isActive) { // Paper - EAR 2 diff --git a/net/minecraft/util/ClassInstanceMultiMap.java b/net/minecraft/util/ClassInstanceMultiMap.java index 2a708ae0d5bb209650b525e3c56051f8b5655074..4c7670224f0c90c1d0d833ff0b3d908846133b4a 100644 --- a/net/minecraft/util/ClassInstanceMultiMap.java +++ b/net/minecraft/util/ClassInstanceMultiMap.java @@ -14,9 +14,9 @@ import java.util.Map.Entry; import net.minecraft.Util; public class ClassInstanceMultiMap extends AbstractCollection { - private final Map, List> byClass = Maps.newHashMap(); + private final Map, List> byClass = new it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap<>(); // DivineMC - Misc Optimizations private final Class baseClass; - private final List allInstances = Lists.newArrayList(); + private final List allInstances = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(); // DivineMC - Misc Optimizations public ClassInstanceMultiMap(Class baseClass) { this.baseClass = baseClass; @@ -56,13 +56,27 @@ public class ClassInstanceMultiMap extends AbstractCollection { } public Collection find(Class type) { + // DivineMC start - Some optimizations + List cached = this.byClass.get(type); + if (cached != null) return (Collection) cached; + if (!this.baseClass.isAssignableFrom(type)) { throw new IllegalArgumentException("Don't know how to search for " + type); } else { - List list = this.byClass - .computeIfAbsent(type, clazz -> this.allInstances.stream().filter(clazz::isInstance).collect(Util.toMutableList())); - return (Collection)Collections.unmodifiableCollection(list); + List list = this.byClass.computeIfAbsent(type, + typeClass -> { + it.unimi.dsi.fastutil.objects.ObjectArrayList ts = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(this.allInstances.size()); + for (Object _allElement : ((it.unimi.dsi.fastutil.objects.ObjectArrayList) this.allInstances).elements()) { + if (typeClass.isInstance(_allElement)) { + ts.add((T) _allElement); + } + } + return ts; + } + ); + return (Collection) list; } + // DivineMC end - Some optimizations } @Override diff --git a/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java b/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java index f28fbf81a417a678726d3f77b3999054676d522e..7ff32b1f93b31fafd13f4e0857d14d85ef1f28c7 100644 --- a/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java +++ b/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java @@ -52,23 +52,23 @@ public class CrudeIncrementalIntIdentityHashBiMap implements IdMap, ca.spo @Nullable @Override - public K byId(int value) { + public synchronized K byId(int value) { // DivineMC - Misc Optimizations return value >= 0 && value < this.byId.length ? this.byId[value] : null; } - private int getValue(int key) { + private synchronized int getValue(int key) { // DivineMC - Misc Optimizations return key == -1 ? -1 : this.values[key]; } - public boolean contains(K value) { + public synchronized boolean contains(K value) { // DivineMC - Misc Optimizations return this.getId(value) != -1; } - public boolean contains(int value) { + public synchronized boolean contains(int value) { // DivineMC - Misc Optimizations return this.byId(value) != null; } - public int add(K object) { + public synchronized int add(K object) { // DivineMC - Misc Optimizations int i = this.nextId(); this.addMapping(object, i); return i; @@ -106,7 +106,7 @@ public class CrudeIncrementalIntIdentityHashBiMap implements IdMap, ca.spo // Paper end - optimise palette reads } - public void addMapping(K object, int intKey) { + public synchronized void addMapping(K object, int intKey) { // DivineMC - Misc Optimizations int max = Math.max(intKey, this.size + 1); if (max >= this.keys.length * 0.8F) { int i = this.keys.length << 1; @@ -173,11 +173,11 @@ public class CrudeIncrementalIntIdentityHashBiMap implements IdMap, ca.spo } @Override - public Iterator iterator() { + public synchronized Iterator iterator() { // DivineMC - Misc Optimizations return Iterators.filter(Iterators.forArray(this.byId), Predicates.notNull()); } - public void clear() { + public synchronized void clear() { // DivineMC - Misc Optimizations Arrays.fill(this.keys, null); Arrays.fill(this.byId, null); this.nextId = 0; diff --git a/net/minecraft/util/Mth.java b/net/minecraft/util/Mth.java index ab3a221c115992d0f4ea921aa92cf0976b815ff4..076a931341da486162f289a5f19d3d6736df7768 100644 --- a/net/minecraft/util/Mth.java +++ b/net/minecraft/util/Mth.java @@ -46,11 +46,11 @@ public class Mth { private static final double[] COS_TAB = new double[257]; public static float sin(float value) { - return SIN[(int)(value * 10430.378F) & 65535]; + return net.caffeinemc.mods.lithium.common.util.math.CompactSineLUT.sin(value); // DivineMC - Math Optimizations } public static float cos(float value) { - return SIN[(int)(value * 10430.378F + 16384.0F) & 65535]; + return net.caffeinemc.mods.lithium.common.util.math.CompactSineLUT.cos(value); // DivineMC - Math Optimizations } public static float sqrt(float value) { @@ -58,18 +58,15 @@ public class Mth { } public static int floor(float value) { - int i = (int)value; - return value < i ? i - 1 : i; + return (int) Math.floor(value); // DivineMC - Math Optimizations } public static int floor(double value) { - int i = (int)value; - return value < i ? i - 1 : i; + return (int) Math.floor(value); // DivineMC - Math Optimizations } public static long lfloor(double value) { - long l = (long)value; - return value < l ? l - 1L : l; + return (long) Math.floor(value); // DivineMC - Math Optimizations } public static float abs(float value) { @@ -81,13 +78,11 @@ public class Mth { } public static int ceil(float value) { - int i = (int)value; - return value > i ? i + 1 : i; + return (int) Math.ceil(value); // DivineMC - Math Optimizations } public static int ceil(double value) { - int i = (int)value; - return value > i ? i + 1 : i; + return (int) Math.ceil(value); // DivineMC - Math Optimizations } public static int clamp(int value, int min, int max) { @@ -123,15 +118,7 @@ public class Mth { } public static double absMax(double x, double y) { - if (x < 0.0) { - x = -x; - } - - if (y < 0.0) { - y = -y; - } - - return Math.max(x, y); + return Math.max(Math.abs(x), Math.abs(y)); // DivineMC - Math Optimizations } public static int floorDiv(int dividend, int divisor) { @@ -162,14 +149,26 @@ public class Mth { return Math.floorMod(x, y); } - public static float positiveModulo(float numerator, float denominator) { + public static float positiveModuloForAnyDenominator(float numerator, float denominator) { // DivineMC - Math Optimizations return (numerator % denominator + denominator) % denominator; } - public static double positiveModulo(double numerator, double denominator) { + public static double positiveModuloForAnyDenominator(double numerator, double denominator) { // DivineMC - Math Optimizations return (numerator % denominator + denominator) % denominator; } + // DivineMC start - Math Optimizations + public static float positiveModuloForPositiveIntegerDenominator(float numerator, float denominator) { + var modulo = numerator % denominator; + return modulo < 0 ? modulo + denominator : modulo; + } + + public static double positiveModuloForPositiveIntegerDenominator(double numerator, double denominator) { + var modulo = numerator % denominator; + return modulo < 0 ? modulo + denominator : modulo; + } + // DivineMC end - Math Optimizations + public static boolean isMultipleOf(int number, int multiple) { return number % multiple == 0; } diff --git a/net/minecraft/util/RandomSource.java b/net/minecraft/util/RandomSource.java index 8516d47b0ba79d91638837199e7ae0fb6cb44a79..71444431b10582f5917c1795275ccdadd2364c3c 100644 --- a/net/minecraft/util/RandomSource.java +++ b/net/minecraft/util/RandomSource.java @@ -12,7 +12,7 @@ public interface RandomSource { double GAUSSIAN_SPREAD_FACTOR = 2.297; static RandomSource create() { - return create(RandomSupport.generateUniqueSeed()); + return createThreadSafe(); // DivineMC - Misc Optimizations } @Deprecated @@ -21,7 +21,7 @@ public interface RandomSource { } static RandomSource create(long seed) { - return new LegacyRandomSource(seed); + return new ThreadSafeLegacyRandomSource(seed); // DivineMC - Misc Optimizations } static RandomSource createNewThreadLocalInstance() { diff --git a/net/minecraft/util/debugchart/DebugSampleSubscriptionTracker.java b/net/minecraft/util/debugchart/DebugSampleSubscriptionTracker.java index a18240418a19a95147341a634527d774f3d5bb92..66f74ad2a194a6676574da2932cf4677f9383ecd 100644 --- a/net/minecraft/util/debugchart/DebugSampleSubscriptionTracker.java +++ b/net/minecraft/util/debugchart/DebugSampleSubscriptionTracker.java @@ -14,7 +14,7 @@ public class DebugSampleSubscriptionTracker { public static final int STOP_SENDING_AFTER_MS = 10000; private final PlayerList playerList; private final Map> subscriptions; - private final Queue subscriptionRequestQueue = new LinkedList<>(); + private final java.util.List subscriptionRequestQueue = java.util.Collections.synchronizedList(new LinkedList<>()); // DivineMC - Misc Optimizations public DebugSampleSubscriptionTracker(PlayerList playerList) { this.playerList = playerList; diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java index 63d619270b98d49c36fba918571d889ac48e8380..f825964c5e7a06d54af68c68d3bf2da0535b51d6 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -149,7 +149,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } // Paper start - Share random for entities to make them more random - public static RandomSource SHARED_RANDOM = new RandomRandomSource(); + public static RandomSource SHARED_RANDOM = new net.minecraft.world.level.levelgen.ThreadSafeLegacyRandomSource(net.minecraft.world.level.levelgen.RandomSupport.generateUniqueSeed()); // DivineMC - Misc Optimizations // Paper start - replace random private static final class RandomRandomSource extends ca.spottedleaf.moonrise.common.util.ThreadUnsafeRandom { public RandomRandomSource() { @@ -1086,28 +1086,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return this.onGround; } - // Paper start - detailed watchdog information - public final Object posLock = new Object(); // Paper - log detailed entity tick information - - @Nullable - private Vec3 moveVector; - private double moveStartX; - private double moveStartY; - private double moveStartZ; - // Paper end - detailed watchdog information - public void move(MoverType type, Vec3 movement) { final Vec3 originalMovement = movement; // Paper - Expose pre-collision velocity - // Paper start - detailed watchdog information ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread("Cannot move an entity off-main"); - synchronized (this.posLock) { - this.moveStartX = this.getX(); - this.moveStartY = this.getY(); - this.moveStartZ = this.getZ(); - this.moveVector = movement; - } - try { - // Paper end - detailed watchdog information if (this.noPhysics) { this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z); } else { @@ -1232,13 +1213,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.setDeltaMovement(this.getDeltaMovement().multiply(blockSpeedFactor, 1.0, blockSpeedFactor)); } } - // Paper start - detailed watchdog information - } finally { - synchronized (this.posLock) { // Paper - this.moveVector = null; - } // Paper - } - // Paper end - detailed watchdog information } private void applyMovementEmissionAndPlaySound(Entity.MovementEmission movementEmission, Vec3 movement, BlockPos pos, BlockState state) { @@ -4523,10 +4497,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess // Paper start - optimise collisions public boolean updateFluidHeightAndDoFluidPushing(final TagKey fluid, final double flowScale) { - if (this.touchingUnloadedChunk()) { - return false; - } - final AABB boundingBox = this.getBoundingBox().deflate(1.0E-3); final Level world = this.level; @@ -4562,7 +4532,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) { for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) { - final net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunkSource.getChunk(currChunkX, currChunkZ, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, false).getSections(); + // DivineMC start - Misc optimizations + final net.minecraft.world.level.chunk.ChunkAccess chunk = chunkSource.getChunk(currChunkX, currChunkZ, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, false); + if (chunk == null) continue; + final net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunk.getSections(); + // DivineMC end - Misc optimizations // bound y for (int currChunkY = minChunkY; currChunkY <= maxChunkY; ++currChunkY) { @@ -4719,9 +4693,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public void setDeltaMovement(Vec3 deltaMovement) { - synchronized (this.posLock) { // Paper - detailed watchdog information this.deltaMovement = deltaMovement; - } // Paper - detailed watchdog information } public void addDeltaMovement(Vec3 addend) { @@ -4829,9 +4801,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } // Paper end - Fix MC-4 if (this.position.x != x || this.position.y != y || this.position.z != z) { - synchronized (this.posLock) { // Paper - detailed watchdog information this.position = new Vec3(x, y, z); - } // Paper - detailed watchdog information int floor = Mth.floor(x); int floor1 = Mth.floor(y); int floor2 = Mth.floor(z); diff --git a/net/minecraft/world/entity/ExperienceOrb.java b/net/minecraft/world/entity/ExperienceOrb.java index 81aa1a91a2ecda3053b22c2eb9e59f0ea2faf7b5..ff4648b3be103446ab401d36c14cc80b48840cab 100644 --- a/net/minecraft/world/entity/ExperienceOrb.java +++ b/net/minecraft/world/entity/ExperienceOrb.java @@ -166,6 +166,7 @@ public class ExperienceOrb extends Entity { if (this.age >= 6000) { this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause } + if (this.count == 0) this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); // DivineMC - discard when count is 0 } } diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java index a58133b53a19e90d4386f57891ee41a5c03228c2..a65c86b411c15bbdfd431dac00e510d2262e65e1 100644 --- a/net/minecraft/world/entity/Mob.java +++ b/net/minecraft/world/entity/Mob.java @@ -698,7 +698,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab if (this.level().getDifficulty() == Difficulty.PEACEFUL && this.shouldDespawnInPeaceful()) { this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause } else if (!this.isPersistenceRequired() && !this.requiresCustomPersistence()) { - Entity nearestPlayer = this.level().findNearbyPlayer(this, -1.0, EntitySelector.PLAYER_AFFECTS_SPAWNING); // Paper - Affects Spawning API + Entity nearestPlayer = this.divinemc$findNearbyPlayer(this.level(), this, -1.0); // Paper - Affects Spawning API // DivineMC - faster player lookup if (nearestPlayer != null) { // Paper start - Configurable despawn distances final io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DespawnRangePair despawnRangePair = this.level().paperConfig().entities.spawning.despawnRanges.get(this.getType().getCategory()); @@ -727,6 +727,19 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab } } + // DivineMC start - faster player lookup + private Player divinemc$findNearbyPlayer(Level instance, Entity entity, double maxDistance) { + final Player closestPlayer = instance.getNearestPlayer(entity, this.getType().getCategory().getDespawnDistance()); + if (closestPlayer != null) { + return closestPlayer; + } else { + final List players = this.level().players(); + if (players.isEmpty()) return null; + return players.get(0); + } + } + // DivineMC end - faster player lookup + @Override protected final void serverAiStep() { this.noActionTime++; diff --git a/net/minecraft/world/level/GameRules.java b/net/minecraft/world/level/GameRules.java index 92fe6acbd530e985da23f50e615817309915122c..c9a2c4f7051639478bd9788911d3c6bead8f5152 100644 --- a/net/minecraft/world/level/GameRules.java +++ b/net/minecraft/world/level/GameRules.java @@ -277,7 +277,7 @@ public class GameRules { } private GameRules(Map, GameRules.Value> rules, FeatureFlagSet enabledFeatures) { - this.rules = rules; + this.rules = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(rules); // DivineMC - lithium: collections.gamerules this.enabledFeatures = enabledFeatures; // Paper start - Perf: Use array for gamerule storage diff --git a/net/minecraft/world/level/LocalMobCapCalculator.java b/net/minecraft/world/level/LocalMobCapCalculator.java index 9641219c190261dea0db5f95f040a705ba0a3ff9..a3fccdeb2c076e12b611683da55d45e00a166417 100644 --- a/net/minecraft/world/level/LocalMobCapCalculator.java +++ b/net/minecraft/world/level/LocalMobCapCalculator.java @@ -13,16 +13,24 @@ import net.minecraft.world.entity.MobCategory; public class LocalMobCapCalculator { private final Long2ObjectMap> playersNearChunk = new Long2ObjectOpenHashMap<>(); - private final Map playerMobCounts = Maps.newHashMap(); + private final Map playerMobCounts = Maps.newConcurrentMap(); // DivineMC - Misc Optimizations private final ChunkMap chunkMap; public LocalMobCapCalculator(ChunkMap chunkMap) { this.chunkMap = chunkMap; } - private List getPlayersNear(ChunkPos pos) { - return this.playersNearChunk.computeIfAbsent(pos.toLong(), key -> this.chunkMap.getPlayersCloseForSpawning(pos)); + // DivineMC start - Some optimizations + private synchronized @org.jetbrains.annotations.NotNull List getPlayersNear(ChunkPos pos) { + List retVal = this.playersNearChunk.get(pos.toLong()); + if (retVal == null) { + List newVal = this.chunkMap.getPlayersCloseForSpawning(pos); + this.playersNearChunk.put(pos.toLong(), newVal); + return newVal; + } + return retVal; } + // DivineMC end - Some optimizations public void addMob(ChunkPos pos, MobCategory category) { for (ServerPlayer serverPlayer : this.getPlayersNear(pos)) { @@ -42,14 +50,14 @@ public class LocalMobCapCalculator { } static class MobCounts { - private final Object2IntMap counts = new Object2IntOpenHashMap<>(MobCategory.values().length); + private final int[] spawnGroupDensities = new int[MobCategory.values().length]; // DivineMC - Misc Optimizations public void add(MobCategory category) { - this.counts.computeInt(category, (key, value) -> value == null ? 1 : value + 1); + this.spawnGroupDensities[category.ordinal()] ++; // DivineMC - Misc Optimizations } public boolean canSpawn(MobCategory category) { - return this.counts.getOrDefault(category, 0) < category.getMaxInstancesPerChunk(); + return this.spawnGroupDensities[category.ordinal()] < category.getMaxInstancesPerChunk(); // DivineMC - Misc Optimizations } } } diff --git a/net/minecraft/world/level/levelgen/blending/Blender.java b/net/minecraft/world/level/levelgen/blending/Blender.java index 01e5b29d6e9a5c53c0e23b61ed0c1d7be1a0fe08..d80df05e40f3941ade5ed320e12f8dcf47e6b247 100644 --- a/net/minecraft/world/level/levelgen/blending/Blender.java +++ b/net/minecraft/world/level/levelgen/blending/Blender.java @@ -144,7 +144,7 @@ public class Blender { private static double heightToOffset(double height) { double d = 1.0; double d1 = height + 0.5; - double d2 = Mth.positiveModulo(d1, 8.0); + double d2 = Mth.positiveModuloForPositiveIntegerDenominator(d1, 8.0); // DivineMC - Math optimizations return 1.0 * (32.0 * (d1 - 128.0) - 3.0 * (d1 - 120.0) * d2 + 3.0 * d2 * d2) / (128.0 * (32.0 - 3.0 * d2)); } diff --git a/net/minecraft/world/level/levelgen/feature/OreFeature.java b/net/minecraft/world/level/levelgen/feature/OreFeature.java index c7b46efd4f08067e2c9c5c8b0e8b71a94a79823d..c7252c636fcea34a866dcc4862b60cef31071666 100644 --- a/net/minecraft/world/level/levelgen/feature/OreFeature.java +++ b/net/minecraft/world/level/levelgen/feature/OreFeature.java @@ -69,7 +69,7 @@ public class OreFeature extends Feature { int height ) { int i = 0; - BitSet bitSet = new BitSet(width * height * width); + BitSet bitSet = org.bxteam.divinemc.util.cache.CachedOrNewBitsGetter.getCachedOrNewBitSet(width * height * width); // DivineMC - Misc Optimizations BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); int i1 = config.size; double[] doubles = new double[i1 * 4]; diff --git a/net/minecraft/world/level/storage/DimensionDataStorage.java b/net/minecraft/world/level/storage/DimensionDataStorage.java index 05361803a929cbcf651a37cf43009e57acb25f3e..5d21d2520dd33889988d8300060e6a41a8334562 100644 --- a/net/minecraft/world/level/storage/DimensionDataStorage.java +++ b/net/minecraft/world/level/storage/DimensionDataStorage.java @@ -39,7 +39,7 @@ import org.slf4j.Logger; public class DimensionDataStorage implements AutoCloseable { private static final Logger LOGGER = LogUtils.getLogger(); private final SavedData.Context context; - public final Map, Optional> cache = new HashMap<>(); + public final Map, Optional> cache = new java.util.concurrent.ConcurrentHashMap<>(); // DivineMC - Misc Optimizations private final DataFixer fixerUpper; private final HolderLookup.Provider registries; private final Path dataFolder; diff --git a/net/minecraft/world/phys/AABB.java b/net/minecraft/world/phys/AABB.java index 5767fbfd7f33c5276fb4335ce473b2e1baca411c..1866d857cabde481f23e861e0db7994bfa84ac40 100644 --- a/net/minecraft/world/phys/AABB.java +++ b/net/minecraft/world/phys/AABB.java @@ -190,13 +190,15 @@ public class AABB { } public AABB intersect(AABB other) { - double max = Math.max(this.minX, other.minX); - double max1 = Math.max(this.minY, other.minY); - double max2 = Math.max(this.minZ, other.minZ); - double min = Math.min(this.maxX, other.maxX); - double min1 = Math.min(this.maxY, other.maxY); - double min2 = Math.min(this.maxZ, other.maxZ); - return new AABB(max, max1, max2, min, min1, min2); + // DivineMC start - Math Optimizations + return new AABB( + this.minX > other.minX ? this.minX : other.minX, + this.minY > other.minY ? this.minY : other.minY, + this.minZ > other.minZ ? this.minZ : other.minZ, + this.maxX < other.maxX ? this.maxX : other.maxX, + this.maxY < other.maxY ? this.maxY : other.maxY, + this.maxZ < other.maxZ ? this.maxZ : other.maxZ + ); } public AABB minmax(AABB other) { @@ -228,16 +230,37 @@ public class AABB { } public boolean intersects(AABB other) { - return this.intersects(other.minX, other.minY, other.minZ, other.maxX, other.maxY, other.maxZ); + // DivineMC start - Math Optimizations + return this.minX < other.maxX && + this.maxX > other.minX && + this.minY < other.maxY && + this.maxY > other.minY && + this.minZ < other.maxZ && + this.maxZ > other.minZ; + // DivineMC end - Math Optimizations } public boolean intersects(double x1, double y1, double z1, double x2, double y2, double z2) { - return this.minX < x2 && this.maxX > x1 && this.minY < y2 && this.maxY > y1 && this.minZ < z2 && this.maxZ > z1; + // DivineMC start - Math Optimizations + return this.minX < x2 && + this.maxX > x1 && + this.minY < y2 && + this.maxY > y1 && + this.minZ < z2 && + this.maxZ > z1; + // DivineMC end - Math Optimizations } public boolean intersects(Vec3 min, Vec3 max) { return this.intersects( - Math.min(min.x, max.x), Math.min(min.y, max.y), Math.min(min.z, max.z), Math.max(min.x, max.x), Math.max(min.y, max.y), Math.max(min.z, max.z) + // DivineMC start - Math Optimizations + min.x < max.x ? min.x : max.x, + min.y < max.y ? min.y : max.y, + min.z < max.z ? min.z : max.z, + min.x > max.x ? min.x : max.x, + min.y > max.y ? min.y : max.y, + min.z > max.z ? min.z : max.z + // DivineMC end - Math Optimizations ); }