Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ In non-strict test, this can give ~60-110% improvement (524ms on Paper, 204ms on
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..ef87b95d53e5ea2555778e6020ea07a11c474961 100644
index b0c5e41fefc7c9adf1a61bd5b52861736657d37e..59dabdf7279c3e96a8d6ce40e5840d526487bf22 100644
--- a/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java
+++ b/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java
@@ -13,17 +13,27 @@ import net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities;
@@ -13,17 +13,26 @@ import net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities;
import net.minecraft.world.phys.AABB;

public class NearestLivingEntitySensor<T extends LivingEntity> extends Sensor<T> {
Expand All @@ -36,15 +36,12 @@ index b0c5e41fefc7c9adf1a61bd5b52861736657d37e..ef87b95d53e5ea2555778e6020ea07a1
- );
- entitiesOfClass.sort(Comparator.comparingDouble(entity::distanceToSqr));
+ // Leaf start - Smart sort entities in NearestLivingEntitySensor
+ double rangeSqr = attributeValue * attributeValue;
+ List<LivingEntity> 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<LivingEntity> sortedList = java.util.Arrays.asList(sorted);
+ it.unimi.dsi.fastutil.objects.ObjectArrayList<LivingEntity> 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);
+ sorter.sort(entitiesOfClass.elements(), entitiesOfClass.size(), entity.position());
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));
brain.setMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES, entitiesOfClass);
brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, new NearestVisibleLivingEntities(level, entity, entitiesOfClass));
+ // Leaf end - Smart sort entities in NearestLivingEntitySensor
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,39 @@ Subject: [PATCH] Smart sort items in NearestItemSensor


diff --git a/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java b/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java
index 09fd13e2d958da8326276c4dadf25bf488aff5ac..651797720f7fc6ff9dc614f4de56053c304b1170 100644
index 09fd13e2d958da8326276c4dadf25bf488aff5ac..a5ec595efe568cccee53b016531a56f721bc99f2 100644
--- a/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java
+++ b/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java
@@ -16,6 +16,12 @@ public class NearestItemSensor extends Sensor<Mob> {
@@ -16,6 +16,13 @@ public class NearestItemSensor extends Sensor<Mob> {
private static final long Y_RANGE = 16L;
public static final int MAX_DISTANCE_TO_WANTED_ITEM = 32;

+ // Leaf start - Smart sort items in NearestItemSensor
+ private final org.dreeam.leaf.util.FastBitRadixSort itemSorter;
+ private static final double MAX_DIST_SQ = (double) MAX_DISTANCE_TO_WANTED_ITEM * MAX_DISTANCE_TO_WANTED_ITEM;
+ public NearestItemSensor() {
+ this.itemSorter = new org.dreeam.leaf.util.FastBitRadixSort();
+ }
+ // Leaf end - Smart sort items in NearestItemSensor
@Override
public Set<MemoryModuleType<?>> requires() {
return ImmutableSet.of(MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM);
@@ -25,10 +31,10 @@ public class NearestItemSensor extends Sensor<Mob> {
@@ -24,8 +31,16 @@ public class NearestItemSensor extends Sensor<Mob> {
@Override
protected void doTick(ServerLevel level, Mob entity) {
Brain<?> brain = entity.getBrain();
List<ItemEntity> 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
- List<ItemEntity> 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));
+ ItemEntity[] sortedItems = this.itemSorter.sort(entitiesOfClass, entity, ItemEntity.class); // Leaf - Smart sort items in NearestItemSensor
+ // Leaf start - Smart sort items in NearestItemSensor
+ 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<ItemEntity> 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
+ itemSorter.sort(entitiesOfClass.elements(), entitiesOfClass.size(), pos);
+ // Leaf end - Smart sort items in NearestItemSensor
// Paper start - Perf: remove streams from hot code
ItemEntity nearest = null;
- for (final ItemEntity itemEntity : entitiesOfClass) {
+ for (final ItemEntity itemEntity : sortedItems) { // Leaf - Smart sort items in NearestItemSensor
if (entity.hasLineOfSight(itemEntity)) { // Paper - Perf: Move predicate into getEntities
nearest = itemEntity;
break;
for (final ItemEntity itemEntity : entitiesOfClass) {
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,32 @@

import net.minecraft.world.entity.Entity;

import java.lang.reflect.Array; // Required for Array.newInstance
import java.util.List;
public final class FastBitRadixSort {

public class FastBitRadixSort {
private static final int SMALL_ARRAY_THRESHOLD = 6;
private static final long[] LONGS = new long[0];
private long[] bitsBuffer = LONGS;

private static final int SMALL_ARRAY_THRESHOLD = 2;
private Entity[] entityBuffer = new Entity[0];
private long[] bitsBuffer = new long[0];

@SuppressWarnings("unchecked")
public <T extends Entity, T_REF extends Entity> T[] sort(List<T> entities, T_REF referenceEntity, Class<T> entityClass) {
int size = entities.size();
public void sort(Object[] entities, int size, net.minecraft.core.Position target) {
if (size <= 1) {
T[] resultArray = (T[]) Array.newInstance(entityClass, size);
return entities.toArray(resultArray);
return;
}

if (this.entityBuffer.length < size) {
this.entityBuffer = new Entity[size];
if (this.bitsBuffer.length < size) {
this.bitsBuffer = new long[size];
}
double tx = target.x();
double ty = target.y();
double tz = target.z();
for (int i = 0; i < size; i++) {
this.entityBuffer[i] = entities.get(i);
this.bitsBuffer[i] = Double.doubleToRawLongBits(
referenceEntity.distanceToSqr(entities.get(i))
);
this.bitsBuffer[i] = Double.doubleToRawLongBits(((Entity) entities[i]).distanceToSqr(tx, ty, tz));
}

fastRadixSort(this.entityBuffer, this.bitsBuffer, 0, size - 1, 62);

T[] resultArray = (T[]) Array.newInstance(entityClass, size);
for (int i = 0; i < size; i++) {
resultArray[i] = entityClass.cast(this.entityBuffer[i]);
}
return resultArray;
fastRadixSort(entities, this.bitsBuffer, 0, size - 1, 62);
}

private void fastRadixSort(
Entity[] ents,
private static void fastRadixSort(
Object[] ents,
long[] bits,
int low,
int high,
Expand Down Expand Up @@ -79,15 +66,15 @@ private void fastRadixSort(
}
}

private void insertionSort(
Entity[] ents,
private static void insertionSort(
Object[] ents,
long[] bits,
int low,
int high
) {
for (int i = low + 1; i <= high; i++) {
int j = i;
Entity currentEntity = ents[j];
Object currentEntity = ents[j];
long currentBits = bits[j];

while (j > low && bits[j - 1] > currentBits) {
Expand All @@ -100,8 +87,8 @@ private void insertionSort(
}
}

private void swap(Entity[] ents, long[] bits, int a, int b) {
Entity tempEntity = ents[a];
private static void swap(Object[] ents, long[] bits, int a, int b) {
Object tempEntity = ents[a];
ents[a] = ents[b];
ents[b] = tempEntity;

Expand Down