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] Remove stream in PlayerSensor Stream operations in PlayerSensor take too much time while ticking Villager farms, so just replace it with for loop =-= Before: 164ms After: 18ms diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/PlayerSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/PlayerSensor.java index 2e887e426dcd79e2dda401f127d0e01ca537e80e..6ef968a5224830959d6f36193810debe7f14e21e 100644 --- a/src/main/java/net/minecraft/world/entity/ai/sensing/PlayerSensor.java +++ b/src/main/java/net/minecraft/world/entity/ai/sensing/PlayerSensor.java @@ -21,17 +21,39 @@ public class PlayerSensor extends Sensor { @Override protected void doTick(ServerLevel world, LivingEntity entity) { - List list = world.players() - .stream() - .filter(EntitySelector.NO_SPECTATORS) - .filter(player -> entity.closerThan(player, 16.0)) - .sorted(Comparator.comparingDouble(entity::distanceToSqr)) - .collect(Collectors.toList()); + // Leaf start - Remove stream in PlayerSensor + List list = new java.util.ArrayList<>(); + for (Player player : world.players()) { + if (!EntitySelector.NO_SPECTATORS.test(player)) { + continue; + } + if (!entity.closerThan(player, 16.0)) { + continue; + } + list.add(player); + } + list.sort(Comparator.comparingDouble(entity::distanceToSqr)); + // Leaf end - Remove stream in PlayerSensor Brain brain = entity.getBrain(); brain.setMemory(MemoryModuleType.NEAREST_PLAYERS, list); - List list2 = list.stream().filter(player -> isEntityTargetable(entity, player)).collect(Collectors.toList()); + // Leaf start - Remove stream in PlayerSensor + List list2 = new java.util.ArrayList<>(); + for (Player player : list) { + if (isEntityTargetable(entity, player)) { + list2.add(player); + } + } + // Leaf end - Remove stream in PlayerSensor brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_PLAYER, list2.isEmpty() ? null : list2.get(0)); - Optional optional = list2.stream().filter(player -> isEntityAttackable(entity, player)).findFirst(); + // Leaf start - Remove stream in PlayerSensor + Optional optional = Optional.empty(); + for (Player player : list2) { + if (isEntityAttackable(entity, player)) { + optional = Optional.of(player); + break; + } + } + // Leaf end - Remove stream in PlayerSensor brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER, optional); } }