9
0
mirror of https://github.com/BX-Team/DivineMC.git synced 2025-12-22 08:19:19 +00:00
Files
DivineMC/divinemc-server/minecraft-patches/features/0014-Some-optimizations.patch
2025-03-16 22:02:11 +03:00

329 lines
18 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Sat, 1 Feb 2025 15:59:29 +0300
Subject: [PATCH] Some optimizations
diff --git a/net/minecraft/core/MappedRegistry.java b/net/minecraft/core/MappedRegistry.java
index 5f752603aa5611ce9d3dd44cc5b70c27ac46a86e..332122c0b700fb743f91f3fed16aade41dceec28 100644
--- a/net/minecraft/core/MappedRegistry.java
+++ b/net/minecraft/core/MappedRegistry.java
@@ -34,10 +34,12 @@ public class MappedRegistry<T> implements WritableRegistry<T> {
private final ResourceKey<? extends Registry<T>> key;
private final ObjectList<Holder.Reference<T>> byId = new ObjectArrayList<>(256);
private final Reference2IntMap<T> toId = Util.make(new Reference2IntOpenHashMap<>(2048), map -> map.defaultReturnValue(-1)); // Paper - Perf: Use bigger expected size to reduce collisions
- private final Map<ResourceLocation, Holder.Reference<T>> byLocation = new HashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions
- private final Map<ResourceKey<T>, Holder.Reference<T>> byKey = new HashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions
- private final Map<T, Holder.Reference<T>> byValue = new IdentityHashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions
- private final Map<ResourceKey<T>, RegistrationInfo> registrationInfos = new IdentityHashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions
+ // DivineMC start - Some optimizations
+ private final Map<ResourceLocation, Holder.Reference<T>> byLocation = new java.util.concurrent.ConcurrentHashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions
+ private final Map<ResourceKey<T>, Holder.Reference<T>> byKey = new java.util.concurrent.ConcurrentHashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions
+ private final Map<T, Holder.Reference<T>> byValue = Collections.synchronizedMap(new IdentityHashMap<>(2048)); // Paper - Perf: Use bigger expected size to reduce collisions
+ private final Map<ResourceKey<T>, 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<TagKey<T>, HolderSet.Named<T>> frozenTags = new IdentityHashMap<>();
MappedRegistry.TagSet<T> allTags = MappedRegistry.TagSet.unbound();
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/util/ClassInstanceMultiMap.java b/net/minecraft/util/ClassInstanceMultiMap.java
index 2a708ae0d5bb209650b525e3c56051f8b5655074..762cba15597623f95a242bdd44742d9b892ad042 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<T> extends AbstractCollection<T> {
- private final Map<Class<?>, List<T>> byClass = Maps.newHashMap();
+ private final Map<Class<?>, List<T>> byClass = new it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap<>(); // DivineMC - Some optimizations
private final Class<T> baseClass;
- private final List<T> allInstances = Lists.newArrayList();
+ private final List<T> allInstances = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(); // DivineMC - Some optimizations
public ClassInstanceMultiMap(Class<T> baseClass) {
this.baseClass = baseClass;
@@ -56,13 +56,27 @@ public class ClassInstanceMultiMap<T> extends AbstractCollection<T> {
}
public <S> Collection<S> find(Class<S> type) {
+ // DivineMC start - Some optimizations
+ List<T> cached = this.byClass.get(type);
+ if (cached != null) return (Collection<S>) cached;
+
if (!this.baseClass.isAssignableFrom(type)) {
throw new IllegalArgumentException("Don't know how to search for " + type);
} else {
- List<? extends T> list = this.byClass
- .computeIfAbsent(type, clazz -> this.allInstances.stream().filter(clazz::isInstance).collect(Util.toMutableList()));
- return (Collection<S>)Collections.unmodifiableCollection(list);
+ List<? extends T> list = this.byClass.computeIfAbsent(type,
+ typeClass -> {
+ it.unimi.dsi.fastutil.objects.ObjectArrayList<T> ts = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(this.allInstances.size());
+ for (Object _allElement : ((it.unimi.dsi.fastutil.objects.ObjectArrayList<T>) this.allInstances).elements()) {
+ if (typeClass.isInstance(_allElement)) {
+ ts.add((T) _allElement);
+ }
+ }
+ return ts;
+ }
+ );
+ return (Collection<S>) list;
}
+ // DivineMC end - Some optimizations
}
@Override
diff --git a/net/minecraft/util/CubicSpline.java b/net/minecraft/util/CubicSpline.java
index f36f8f2d49d4eba5c80eb243883749d6f831eb8a..5abd899c88683cb79bb8f02e43c4bfbe8563f496 100644
--- a/net/minecraft/util/CubicSpline.java
+++ b/net/minecraft/util/CubicSpline.java
@@ -254,31 +254,47 @@ public interface CubicSpline<C, I extends ToFloatFunction<C>> extends ToFloatFun
@Override
public float apply(C object) {
- float f = this.coordinate.apply(object);
- int i = findIntervalStart(this.locations, f);
- int i1 = this.locations.length - 1;
- if (i < 0) {
- return linearExtend(f, this.locations, this.values.get(0).apply(object), this.derivatives, 0);
- } else if (i == i1) {
- return linearExtend(f, this.locations, this.values.get(i1).apply(object), this.derivatives, i1);
+ // DivineMC start - Some optimizations
+ float point = this.coordinate.apply(object);
+ int rangeForLocation = findIntervalStart(this.locations, point);
+ int last = this.locations.length - 1;
+ if (rangeForLocation < 0) {
+ return linearExtend(point, this.locations, this.values.get(0).apply(object), this.derivatives, 0);
+ } else if (rangeForLocation == last) {
+ return linearExtend(point, this.locations, this.values.get(last).apply(object), this.derivatives, last);
} else {
- float f1 = this.locations[i];
- float f2 = this.locations[i + 1];
- float f3 = (f - f1) / (f2 - f1);
- ToFloatFunction<C> toFloatFunction = (ToFloatFunction<C>)this.values.get(i);
- ToFloatFunction<C> toFloatFunction1 = (ToFloatFunction<C>)this.values.get(i + 1);
- float f4 = this.derivatives[i];
- float f5 = this.derivatives[i + 1];
- float f6 = toFloatFunction.apply(object);
- float f7 = toFloatFunction1.apply(object);
- float f8 = f4 * (f2 - f1) - (f7 - f6);
- float f9 = -f5 * (f2 - f1) + (f7 - f6);
- return Mth.lerp(f3, f6, f7) + f3 * (1.0F - f3) * Mth.lerp(f3, f8, f9);
+ float loc0 = this.locations[rangeForLocation];
+ float loc1 = this.locations[rangeForLocation + 1];
+ float locDist = loc1 - loc0;
+ float k = (point - loc0) / locDist;
+ float n = this.values.get(rangeForLocation).apply(object);
+ float o = this.values.get(rangeForLocation + 1).apply(object);
+ float onDist = o - n;
+ float p = this.derivatives[rangeForLocation] * locDist - onDist;
+ float q = -this.derivatives[rangeForLocation + 1] * locDist + onDist;
+ return Mth.lerp(k, n, o) + k * (1.0F - k) * Mth.lerp(k, p, q);
}
+ // DivineMC end - Some optimizations
}
private static int findIntervalStart(float[] locations, float start) {
- return Mth.binarySearch(0, locations.length, i -> start < locations[i]) - 1;
+ // DivineMC start - Some optimizations
+ int min = 0;
+ int i = locations.length;
+
+ while (i > 0) {
+ int j = i / 2;
+ int k = min + j;
+ if (start < locations[k]) {
+ i = j;
+ } else {
+ min = k + 1;
+ i -= j + 1;
+ }
+ }
+
+ return min - 1;
+ // DivineMC end - Some optimizations
}
@VisibleForTesting
@@ -313,5 +329,27 @@ public interface CubicSpline<C, I extends ToFloatFunction<C>> extends ToFloatFun
this.derivatives
);
}
+
+ // DivineMC start - Some optimizations
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Multipoint<?, ?> that = (Multipoint<?, ?>) o;
+ return java.util.Objects.equals(coordinate, that.coordinate()) && java.util.Arrays.equals(locations, that.locations()) && java.util.Objects.equals(values, that.values()) && java.util.Arrays.equals(derivatives, that.derivatives());
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 1;
+
+ result = 31 * result + java.util.Objects.hashCode(coordinate);
+ result = 31 * result + java.util.Arrays.hashCode(locations);
+ result = 31 * result + java.util.Objects.hashCode(values);
+ result = 31 * result + java.util.Arrays.hashCode(derivatives);
+
+ return result;
+ }
+ // DivineMC end - Some optimizations
}
}
diff --git a/net/minecraft/util/RandomSource.java b/net/minecraft/util/RandomSource.java
index 98a54bc4de251014342cda6d0951b7fea79ce553..cd17a4c7f02abf16fcb3b793c10d8b86d47b7974 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 - Some optimizations
}
@Deprecated
@@ -21,7 +21,7 @@ public interface RandomSource {
}
static RandomSource create(long seed) {
- return new LegacyRandomSource(seed);
+ return new ThreadSafeLegacyRandomSource(seed); // DivineMC - Some optimizations
}
static RandomSource createNewThreadLocalInstance() {
diff --git a/net/minecraft/util/debugchart/DebugSampleSubscriptionTracker.java b/net/minecraft/util/debugchart/DebugSampleSubscriptionTracker.java
index 15de39fa82c7aea18298509fe9587d027c30cc15..c199f99efe25737602a3565ca6f70177571ff886 100644
--- a/net/minecraft/util/debugchart/DebugSampleSubscriptionTracker.java
+++ b/net/minecraft/util/debugchart/DebugSampleSubscriptionTracker.java
@@ -15,7 +15,7 @@ public class DebugSampleSubscriptionTracker {
public static final int STOP_SENDING_AFTER_MS = 10000;
private final PlayerList playerList;
private final EnumMap<RemoteDebugSampleType, Map<ServerPlayer, DebugSampleSubscriptionTracker.SubscriptionStartedAt>> subscriptions;
- private final Queue<DebugSampleSubscriptionTracker.SubscriptionRequest> subscriptionRequestQueue = new LinkedList<>();
+ private final java.util.List<SubscriptionRequest> subscriptionRequestQueue = java.util.Collections.synchronizedList(new LinkedList<>()); // DivineMC - Some optimizations
public DebugSampleSubscriptionTracker(PlayerList playerList) {
this.playerList = playerList;
diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java
index bc22d67bba9b1ebb6bef84f5326375100d24461d..4aa5ecf3e7a7f58505de583dba7738dc1a596d72 100644
--- a/net/minecraft/world/entity/Mob.java
+++ b/net/minecraft/world/entity/Mob.java
@@ -841,7 +841,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());
@@ -870,6 +870,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<? extends Player> 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/LocalMobCapCalculator.java b/net/minecraft/world/level/LocalMobCapCalculator.java
index 9641219c190261dea0db5f95f040a705ba0a3ff9..91966607f8f48b56e2c7e9389bd7d8acda99a48d 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<List<ServerPlayer>> playersNearChunk = new Long2ObjectOpenHashMap<>();
- private final Map<ServerPlayer, LocalMobCapCalculator.MobCounts> playerMobCounts = Maps.newHashMap();
+ private final Map<ServerPlayer, LocalMobCapCalculator.MobCounts> playerMobCounts = Maps.newConcurrentMap(); // DivineMC - Some optimizations
private final ChunkMap chunkMap;
public LocalMobCapCalculator(ChunkMap chunkMap) {
this.chunkMap = chunkMap;
}
- private List<ServerPlayer> 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<ServerPlayer> getPlayersNear(ChunkPos pos) {
+ List<ServerPlayer> retVal = this.playersNearChunk.get(pos.toLong());
+ if (retVal == null) {
+ List<ServerPlayer> 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<MobCategory> counts = new Object2IntOpenHashMap<>(MobCategory.values().length);
+ private final int[] spawnGroupDensities = new int[MobCategory.values().length]; // DivineMC - Some optimizations
public void add(MobCategory category) {
- this.counts.computeInt(category, (key, value) -> value == null ? 1 : value + 1);
+ this.spawnGroupDensities[category.ordinal()] ++; // DivineMC - Some optimizations
}
public boolean canSpawn(MobCategory category) {
- return this.counts.getOrDefault(category, 0) < category.getMaxInstancesPerChunk();
+ return this.spawnGroupDensities[category.ordinal()] < category.getMaxInstancesPerChunk(); // DivineMC - Some optimizations
}
}
}
diff --git a/net/minecraft/world/level/storage/DimensionDataStorage.java b/net/minecraft/world/level/storage/DimensionDataStorage.java
index d9a3b5a2e6495b7e22c114506c2bd1e406f58f8f..a6e03345afd6d8a38e06a43c59103209618baa14 100644
--- a/net/minecraft/world/level/storage/DimensionDataStorage.java
+++ b/net/minecraft/world/level/storage/DimensionDataStorage.java
@@ -34,7 +34,7 @@ import org.slf4j.Logger;
public class DimensionDataStorage implements AutoCloseable {
private static final Logger LOGGER = LogUtils.getLogger();
- public final Map<String, Optional<SavedData>> cache = new HashMap<>();
+ public final Map<String, Optional<SavedData>> cache = new java.util.concurrent.ConcurrentHashMap<>(); // DivineMC - Concurrent HashMap
private final DataFixer fixerUpper;
private final HolderLookup.Provider registries;
private final Path dataFolder;