c97ce029e9
PaperMC believes that 1.16.2 is now ready for general release as we fixed the main issue plagueing the 1.16.x release, the MapLike data conversion issues. Until now, it was not safe for a server to convert a world to 1.16.2 without data conversion issues around villages and potentially other things. If you did, those MapLike errors meant something went wrong. This is now resolved. Big thanks to all those that helped, notably @BillyGalbreath and @Proximyst who did large parts of the update process with me. Please as always, backup your worlds and test before updating to 1.16.2! If you update to 1.16.2, there is no going back to an older build than this. --------------------------------- Co-authored-by: William Blake Galbreath <Blake.Galbreath@GMail.com> Co-authored-by: Mariell Hoversholm <proximyst@proximyst.com> Co-authored-by: krolik-exe <69214078+krolik-exe@users.noreply.github.com> Co-authored-by: BillyGalbreath <BillyGalbreath@users.noreply.github.com> Co-authored-by: stonar96 <minecraft.stonar96@gmail.com> Co-authored-by: Shane Freeder <theboyetronic@gmail.com> Co-authored-by: Jason <jasonpenilla2@me.com> Co-authored-by: kashike <kashike@vq.lc> Co-authored-by: Aurora <21148213+aurorasmiles@users.noreply.github.com> Co-authored-by: KennyTV <kennytv@t-online.de> Co-authored-by: commandblockguy <commandblockguy1@gmail.com> Co-authored-by: DigitalRegent <misterwener@gmail.com> Co-authored-by: ishland <ishlandmc@yeah.net>
135 Zeilen
6.5 KiB
Diff
135 Zeilen
6.5 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Aikar <aikar@aikar.co>
|
|
Date: Tue, 4 Aug 2020 22:24:15 +0200
|
|
Subject: [PATCH] Optimize Pathfinder - Remove Streams / Optimized collections
|
|
|
|
I utilized the IDE to convert streams to non streams code, so shouldn't
|
|
be any risk of behavior change. Only did minor optimization of the
|
|
generated code set to remove unnecessary things.
|
|
|
|
I expect us to just drop this patch on next major update and re-apply
|
|
it with the IDE again and re-apply the collections optimization.
|
|
|
|
Optimize collection by creating a list instead of a set of the key and value.
|
|
|
|
This lets us get faster foreach iteration, as well as avoids map lookups on
|
|
the values when needed.
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/Pathfinder.java b/src/main/java/net/minecraft/server/Pathfinder.java
|
|
index b31d1f73ce0f067e352868b53eab7557c34b17eb..997982136cdd2a0d922e501473e0d4d1aabf567a 100644
|
|
--- a/src/main/java/net/minecraft/server/Pathfinder.java
|
|
+++ b/src/main/java/net/minecraft/server/Pathfinder.java
|
|
@@ -30,9 +30,12 @@ public class Pathfinder {
|
|
this.d.a();
|
|
this.c.a(chunkcache, entityinsentient);
|
|
PathPoint pathpoint = this.c.b();
|
|
- Map<PathDestination, BlockPosition> map = (Map) set.stream().collect(Collectors.toMap((blockposition) -> {
|
|
- return this.c.a((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ());
|
|
- }, Function.identity()));
|
|
+ // Paper start - remove streams - and optimize collection
|
|
+ List<Map.Entry<PathDestination, BlockPosition>> map = Lists.newArrayList();
|
|
+ for (BlockPosition blockposition : set) {
|
|
+ map.add(new java.util.AbstractMap.SimpleEntry<>(this.c.a((double) blockposition.getX(), blockposition.getY(), blockposition.getZ()), blockposition));
|
|
+ }
|
|
+ // Paper end
|
|
PathEntity pathentity = this.a(pathpoint, map, f, i, f1);
|
|
|
|
this.c.a();
|
|
@@ -40,17 +43,17 @@ public class Pathfinder {
|
|
}
|
|
|
|
@Nullable
|
|
- private PathEntity a(PathPoint pathpoint, Map<PathDestination, BlockPosition> map, float f, int i, float f1) {
|
|
- Set<PathDestination> set = map.keySet();
|
|
+ private PathEntity a(PathPoint pathpoint, List<Map.Entry<PathDestination, BlockPosition>> list, float f, int i, float f1) { // Paper - optimize collection
|
|
+ //Set<PathDestination> set = map.keySet(); // Paper
|
|
|
|
pathpoint.e = 0.0F;
|
|
- pathpoint.f = this.a(pathpoint, set);
|
|
+ pathpoint.f = this.a(pathpoint, list); // Paper - optimize collection
|
|
pathpoint.g = pathpoint.f;
|
|
this.d.a();
|
|
this.d.a(pathpoint);
|
|
Set<PathPoint> set1 = ImmutableSet.of();
|
|
int j = 0;
|
|
- Set<PathDestination> set2 = Sets.newHashSetWithExpectedSize(set.size());
|
|
+ List<Map.Entry<PathDestination, BlockPosition>> set2 = Lists.newArrayListWithExpectedSize(list.size()); // Paper - optimize collection
|
|
int k = (int) ((float) this.b * f1);
|
|
|
|
while (!this.d.e()) {
|
|
@@ -62,14 +65,15 @@ public class Pathfinder {
|
|
PathPoint pathpoint1 = this.d.c();
|
|
|
|
pathpoint1.i = true;
|
|
- Iterator iterator = set.iterator();
|
|
-
|
|
- while (iterator.hasNext()) {
|
|
- PathDestination pathdestination = (PathDestination) iterator.next();
|
|
+ // Paper start - optimize collection
|
|
+ for (int i1 = 0; i1 < list.size(); i1++) {
|
|
+ Map.Entry<PathDestination, BlockPosition> entry = list.get(i1);
|
|
+ PathDestination pathdestination = entry.getKey();
|
|
|
|
if (pathpoint1.c((PathPoint) pathdestination) <= (float) i) {
|
|
pathdestination.e();
|
|
- set2.add(pathdestination);
|
|
+ set2.add(entry);
|
|
+ // Paper end
|
|
}
|
|
}
|
|
|
|
@@ -90,7 +94,7 @@ public class Pathfinder {
|
|
if (pathpoint2.j < f && (!pathpoint2.c() || f3 < pathpoint2.e)) {
|
|
pathpoint2.h = pathpoint1;
|
|
pathpoint2.e = f3;
|
|
- pathpoint2.f = this.a(pathpoint2, set) * 1.5F;
|
|
+ pathpoint2.f = this.a(pathpoint2, list) * 1.5F; // Paper - list instead of set
|
|
if (pathpoint2.c()) {
|
|
this.d.a(pathpoint2, pathpoint2.e + pathpoint2.f);
|
|
} else {
|
|
@@ -102,28 +106,29 @@ public class Pathfinder {
|
|
}
|
|
}
|
|
|
|
- Optional<PathEntity> optional = !set2.isEmpty() ? set2.stream().map((pathdestination1) -> {
|
|
- return this.a(pathdestination1.d(), (BlockPosition) map.get(pathdestination1), true);
|
|
- }).min(Comparator.comparingInt(PathEntity::e)) : set.stream().map((pathdestination1) -> {
|
|
- return this.a(pathdestination1.d(), (BlockPosition) map.get(pathdestination1), false);
|
|
- }).min(Comparator.comparingDouble(PathEntity::n).thenComparingInt(PathEntity::e));
|
|
-
|
|
- if (!optional.isPresent()) {
|
|
- return null;
|
|
- } else {
|
|
- PathEntity pathentity = (PathEntity) optional.get();
|
|
-
|
|
- return pathentity;
|
|
+ // Paper start - remove streams - and optimize collection
|
|
+ PathEntity best = null;
|
|
+ boolean useSet1 = set2.isEmpty();
|
|
+ Comparator<PathEntity> comparator = useSet1 ? Comparator.comparingInt(PathEntity::e)
|
|
+ : Comparator.comparingDouble(PathEntity::n).thenComparingInt(PathEntity::e);
|
|
+ for (Map.Entry<PathDestination, BlockPosition> entry : useSet1 ? list : set2) {
|
|
+ PathEntity pathEntity = this.a(entry.getKey().d(), entry.getValue(), !useSet1);
|
|
+ if (best == null || comparator.compare(pathEntity, best) < 0)
|
|
+ best = pathEntity;
|
|
}
|
|
+ return best;
|
|
+ // Paper end
|
|
}
|
|
|
|
- private float a(PathPoint pathpoint, Set<PathDestination> set) {
|
|
+ private float a(PathPoint pathpoint, List<Map.Entry<PathDestination, BlockPosition>> list) { // Paper - optimize collection
|
|
float f = Float.MAX_VALUE;
|
|
|
|
float f1;
|
|
|
|
- for (Iterator iterator = set.iterator(); iterator.hasNext(); f = Math.min(f1, f)) {
|
|
- PathDestination pathdestination = (PathDestination) iterator.next();
|
|
+ // Paper start - optimize collection
|
|
+ for (int i = 0, listSize = list.size(); i < listSize; f = Math.min(f1, f), i++) { // Paper
|
|
+ PathDestination pathdestination = list.get(i).getKey(); // Paper
|
|
+ // Paper end
|
|
|
|
f1 = pathpoint.a(pathdestination);
|
|
pathdestination.a(f1, pathpoint);
|