From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: hayanesuru Date: Thu, 28 Aug 2025 17:10:34 +0900 Subject: [PATCH] fast bit radix sort Co-authored-by: Taiyou06 diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java index f846498b87ba751dbd4024424c0dd4f8496309b7..e2799c3731d2c92e9ba9e87af36cbea944efe169 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -1102,6 +1102,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public final org.dreeam.leaf.world.NatureSpawnChunkMap natureSpawnChunkMap = new org.dreeam.leaf.world.NatureSpawnChunkMap(); // Leaf - optimize mob spawning public final org.dreeam.leaf.world.RandomTickSystem randomTickSystem = new org.dreeam.leaf.world.RandomTickSystem(); // Leaf - optimize random tick public final org.dreeam.leaf.world.EntityCollisionCache entityCollisionCache = new org.dreeam.leaf.world.EntityCollisionCache(); // Leaf - cache collision list + public final org.dreeam.leaf.util.FastBitRadixSort fastBitRadixSort = new org.dreeam.leaf.util.FastBitRadixSort(); // Leaf - fast bit radix sort public void tickChunk(LevelChunk chunk, int randomTickSpeed) { final net.minecraft.world.level.levelgen.BitRandomSource simpleRandom = this.simpleRandom; // Paper - optimise random ticking // Leaf - Faster random generator - upcasting diff --git a/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java b/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java index 09fd13e2d958da8326276c4dadf25bf488aff5ac..063cab1fbd8dd3a483346242659fe273d3000cc6 100644 --- a/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java +++ b/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java @@ -15,6 +15,7 @@ public class NearestItemSensor extends Sensor { private static final long XZ_RANGE = 32L; private static final long Y_RANGE = 16L; public static final int MAX_DISTANCE_TO_WANTED_ITEM = 32; + private static final double MAX_DIST_SQ = (double) MAX_DISTANCE_TO_WANTED_ITEM * MAX_DISTANCE_TO_WANTED_ITEM; // Leaf - quick sort @Override public Set> requires() { @@ -24,8 +25,16 @@ public class NearestItemSensor extends Sensor { @Override protected void doTick(ServerLevel level, Mob entity) { Brain brain = entity.getBrain(); - List entitiesOfClass = level.getEntitiesOfClass(ItemEntity.class, entity.getBoundingBox().inflate(32.0, 16.0, 32.0), itemEntity -> itemEntity.closerThan(entity, MAX_DISTANCE_TO_WANTED_ITEM) && entity.wantsToPickUp(level, itemEntity.getItem())); // Paper - Perf: Move predicate into getEntities - entitiesOfClass.sort(Comparator.comparingDouble(entity::distanceToSqr)); + // Leaf start - fast bit radix sort + net.minecraft.core.Position pos = entity.position(); + double x = pos.x(); + double y = pos.y(); + double z = pos.z(); + net.minecraft.world.phys.AABB boundingBox = entity.getBoundingBox().inflate(32.0, 16.0, 32.0); + it.unimi.dsi.fastutil.objects.ObjectArrayList entitiesOfClass = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(); + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel) level).moonrise$getEntityLookup().getEntities(ItemEntity.class, null, boundingBox, entitiesOfClass, (ItemEntity itemEntity) -> itemEntity.distanceToSqr(x, y, z) < MAX_DIST_SQ && entity.wantsToPickUp(level, itemEntity.getItem())); // Paper - Perf: Move predicate into getEntities + level.fastBitRadixSort.sort(entitiesOfClass.elements(), entitiesOfClass.size(), pos); + // Leaf end - fast bit radix sort // Paper start - Perf: remove streams from hot code ItemEntity nearest = null; for (final ItemEntity itemEntity : entitiesOfClass) { diff --git a/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java b/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java index b0c5e41fefc7c9adf1a61bd5b52861736657d37e..51a6302ed5daf512acc6bed915f954ac76559270 100644 --- a/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java +++ b/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java @@ -17,10 +17,11 @@ public class NearestLivingEntitySensor extends Sensor protected void doTick(ServerLevel level, T entity) { double attributeValue = entity.getAttributeValue(Attributes.FOLLOW_RANGE); AABB aabb = entity.getBoundingBox().inflate(attributeValue, attributeValue, attributeValue); - List entitiesOfClass = level.getEntitiesOfClass( - LivingEntity.class, aabb, matchableEntity -> matchableEntity != entity && matchableEntity.isAlive() - ); - entitiesOfClass.sort(Comparator.comparingDouble(entity::distanceToSqr)); + // Leaf start - fast bit radix sort + it.unimi.dsi.fastutil.objects.ObjectArrayList entitiesOfClass = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(); + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel) level).moonrise$getEntityLookup().getEntities(LivingEntity.class, entity, aabb, entitiesOfClass, LivingEntity::isAlive); + level.fastBitRadixSort.sort(entitiesOfClass.elements(), entitiesOfClass.size(), entity.position()); + // Leaf end - fast bit radix sort Brain brain = entity.getBrain(); brain.setMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES, entitiesOfClass); brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, new NearestVisibleLivingEntities(level, entity, entitiesOfClass)); diff --git a/net/minecraft/world/entity/ai/sensing/PlayerSensor.java b/net/minecraft/world/entity/ai/sensing/PlayerSensor.java index fa438315b4ed8e9394383b82b89ecb04bac3399f..44942f1fa1f543e81b1553e51c057de437f10e93 100644 --- a/net/minecraft/world/entity/ai/sensing/PlayerSensor.java +++ b/net/minecraft/world/entity/ai/sensing/PlayerSensor.java @@ -27,18 +27,26 @@ public class PlayerSensor extends Sensor { @Override protected void doTick(ServerLevel level, LivingEntity entity) { // Leaf start - Remove stream in PlayerSensor - List list = new java.util.ArrayList<>(); + // Leaf start - fast bit radix sort + it.unimi.dsi.fastutil.objects.ObjectArrayList list = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(); + double distance = this.getFollowDistance(entity); + double distSq = distance * distance; + net.minecraft.world.phys.Vec3 vec3 = entity.position(); + double tx = vec3.x(); + double ty = vec3.y(); + double tz = vec3.z(); for (Player serverPlayer : level.players()) { if (!EntitySelector.NO_SPECTATORS.test(serverPlayer)) { continue; } - if (!entity.closerThan(serverPlayer, this.getFollowDistance(entity))) { + if (serverPlayer.distanceToSqr(tx, ty, tz) >= distSq) { continue; } list.add(serverPlayer); } - list.sort(Comparator.comparingDouble(entity::distanceToSqr)); + level.fastBitRadixSort.sort(list.elements(), list.size(), vec3); + // Leaf end - fast bit radix sort // Leaf end - Remove stream in PlayerSensor Brain brain = entity.getBrain(); brain.setMemory(MemoryModuleType.NEAREST_PLAYERS, list);