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/net/minecraft/world/entity/ai/sensing/PlayerSensor.java b/net/minecraft/world/entity/ai/sensing/PlayerSensor.java index 6233e6b48aaa69ba9f577d0b480b1cdf2f55d16e..996c93f2b7ffd83134535f75c0ead45cc34ef13c 100644 --- a/net/minecraft/world/entity/ai/sensing/PlayerSensor.java +++ b/net/minecraft/world/entity/ai/sensing/PlayerSensor.java @@ -22,17 +22,40 @@ public class PlayerSensor extends Sensor { @Override protected void doTick(ServerLevel level, LivingEntity entity) { - List list = level.players() - .stream() - .filter(EntitySelector.NO_SPECTATORS) - .filter(serverPlayer -> entity.closerThan(serverPlayer, this.getFollowDistance(entity))) - .sorted(Comparator.comparingDouble(entity::distanceToSqr)) - .collect(Collectors.toList()); + // Leaf start - Remove stream in PlayerSensor + List list = new java.util.ArrayList<>(); + for (Player serverPlayer : level.players()) { + if (!EntitySelector.NO_SPECTATORS.test(serverPlayer)) { + continue; + } + if (!entity.closerThan(serverPlayer, this.getFollowDistance(entity))) { + continue; + } + + list.add(serverPlayer); + } + list.sort(Comparator.comparingDouble(entity::distanceToSqr)); + // Leaf end - Remove stream in PlayerSensor Brain brain = entity.getBrain(); brain.setMemory(MemoryModuleType.NEAREST_PLAYERS, list); - List list1 = list.stream().filter(player -> isEntityTargetable(level, entity, player)).collect(Collectors.toList()); + // Leaf start - Remove stream in PlayerSensor + List list1 = new java.util.ArrayList<>(); + for (Player player : list) { + if (isEntityTargetable(level, entity, player)) { + list1.add(player); + } + } + // Leaf end - Remove stream in PlayerSensor brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_PLAYER, list1.isEmpty() ? null : list1.get(0)); - Optional optional = list1.stream().filter(player -> isEntityAttackable(level, entity, player)).findFirst(); + // Leaf start - Remove stream in PlayerSensor + Optional optional = Optional.empty(); + for (Player player : list1) { + if (isEntityAttackable(level, entity, player)) { + optional = Optional.of(player); + break; + } + } + // Leaf end - Remove stream in PlayerSensor brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER, optional); }