mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-29 11:59:24 +00:00
Originally vanilla logic is to use stream, and Mojang switched it to Guava's Collections2 since 1.21.4. It is much faster than using stream or manually adding to a new ArrayList. Manually adding to a new ArrayList requires allocating a new object array. However, the Collections2 lazy handles filter condition on iteration, so much better.
52 lines
3.0 KiB
Diff
52 lines
3.0 KiB
Diff
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 <kaandindar21@gmail.com>
|
|
|
|
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..ef87b95d53e5ea2555778e6020ea07a11c474961 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;
|
|
import net.minecraft.world.phys.AABB;
|
|
|
|
public class NearestLivingEntitySensor<T extends LivingEntity> extends Sensor<T> {
|
|
+
|
|
+ // Leaf start - Smart sort entities in NearestLivingEntitySensor
|
|
+ private final org.dreeam.leaf.util.FastBitRadixSort sorter;
|
|
+ public NearestLivingEntitySensor() {
|
|
+ this.sorter = new org.dreeam.leaf.util.FastBitRadixSort();
|
|
+ }
|
|
+ // Leaf end - Smart sort entities in NearestLivingEntitySensor
|
|
+
|
|
@Override
|
|
protected void doTick(ServerLevel level, T entity) {
|
|
double attributeValue = entity.getAttributeValue(Attributes.FOLLOW_RANGE);
|
|
AABB aabb = entity.getBoundingBox().inflate(attributeValue, attributeValue, attributeValue);
|
|
- List<LivingEntity> entitiesOfClass = level.getEntitiesOfClass(
|
|
- LivingEntity.class, aabb, matchableEntity -> matchableEntity != entity && matchableEntity.isAlive()
|
|
- );
|
|
- 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);
|
|
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));
|
|
+ // Leaf end - Smart sort entities in NearestLivingEntitySensor
|
|
}
|
|
|
|
@Override
|