From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> Date: Tue, 9 Nov 2077 00:00:00 +0800 Subject: [PATCH] Smart sort entities in NearestLivingEntitySensor Co-authored-by: Taiyou06 FastBitRadix Sort will be used. (see https://ieeexplore.ieee.org/document/7822019 for more) When entity count reached the threshold, Bucket Sort will be used. In non-strict test, this can give ~60-110% improvement (524ms on Paper, 204ms on Leaf), under 625 villagers situation. diff --git a/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java b/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java index b0c5e41fefc7c9adf1a61bd5b52861736657d37e..a887bb8ed2318d6ee39be350a1d0e7223ecf3ff5 100644 --- a/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java +++ b/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java @@ -13,17 +13,28 @@ import net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities; import net.minecraft.world.phys.AABB; public class NearestLivingEntitySensor extends Sensor { + + // Leaf start - Smart sort entities in NearestLivingEntitySensor + private final org.dreeam.leaf.util.fastBitRadixSort sorter; + // Leaf end - Smart sort entities in NearestLivingEntitySensor + public NearestLivingEntitySensor() { + this.sorter = new org.dreeam.leaf.util.fastBitRadixSort(); + } + @Override protected void doTick(ServerLevel level, T entity) { double attributeValue = entity.getAttributeValue(Attributes.FOLLOW_RANGE); + double rangeSqr = attributeValue * attributeValue; 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)); + + List entities = level.getEntitiesOfClass(LivingEntity.class, aabb, e -> e != entity && e.isAlive() && entity.distanceToSqr(e) <= rangeSqr); + + LivingEntity[] sorted = this.sorter.sort(entities, entity, LivingEntity.class); + List sortedList = java.util.Arrays.asList(sorted); + Brain brain = entity.getBrain(); - brain.setMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES, entitiesOfClass); - brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, new NearestVisibleLivingEntities(level, entity, entitiesOfClass)); + brain.setMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES, sortedList); + brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, new NearestVisibleLivingEntities(level, entity, sortedList)); } @Override