Multiple memory and performance optimizations (removing streams)
This commit is contained in:
parent
748e6447e3
commit
92d2907d14
4 changed files with 245 additions and 0 deletions
|
@ -0,0 +1,59 @@
|
||||||
|
From e5ba87668be36b649b80633170a33e7ad3fae019 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Spottedleaf <spottedleaf@spottedleaf.dev>
|
||||||
|
Date: Mon, 6 Apr 2020 18:35:09 -0700
|
||||||
|
Subject: [PATCH] Reduce Either Optional allocation
|
||||||
|
|
||||||
|
In order to get chunk values, we shouldn't need to create
|
||||||
|
an optional each time.
|
||||||
|
|
||||||
|
diff --git a/src/main/java/com/mojang/datafixers/util/Either.java b/src/main/java/com/mojang/datafixers/util/Either.java
|
||||||
|
index a90adac7b..efae74b71 100644
|
||||||
|
--- a/src/main/java/com/mojang/datafixers/util/Either.java
|
||||||
|
+++ b/src/main/java/com/mojang/datafixers/util/Either.java
|
||||||
|
@@ -22,10 +22,10 @@ public abstract class Either<L, R> implements App<Either.Mu<R>, L> {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class Left<L, R> extends Either<L, R> {
|
||||||
|
- private final L value;
|
||||||
|
+ private final L value; private final Optional<L> valueOptional; // Paper - reduce the optional allocation...
|
||||||
|
|
||||||
|
public Left(final L value) {
|
||||||
|
- this.value = value;
|
||||||
|
+ this.value = value; this.valueOptional = Optional.of(value); // Paper - reduce the optional allocation...
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@@ -51,7 +51,7 @@ public abstract class Either<L, R> implements App<Either.Mu<R>, L> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<L> left() {
|
||||||
|
- return Optional.of(value);
|
||||||
|
+ return this.valueOptional; // Paper - reduce the optional allocation...
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@@ -83,10 +83,10 @@ public abstract class Either<L, R> implements App<Either.Mu<R>, L> {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class Right<L, R> extends Either<L, R> {
|
||||||
|
- private final R value;
|
||||||
|
+ private final R value; private final Optional<R> valueOptional; // Paper - reduce the optional allocation...
|
||||||
|
|
||||||
|
public Right(final R value) {
|
||||||
|
- this.value = value;
|
||||||
|
+ this.value = value; this.valueOptional = Optional.of(value); // Paper - reduce the optional allocation...
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@@ -117,7 +117,7 @@ public abstract class Either<L, R> implements App<Either.Mu<R>, L> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<R> right() {
|
||||||
|
- return Optional.of(value);
|
||||||
|
+ return this.valueOptional; // Paper - reduce the optional allocation...
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
From 7d32a5500fd79455112616c6a1646fb71b1dac43 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Spottedleaf <spottedleaf@spottedleaf.dev>
|
||||||
|
Date: Mon, 6 Apr 2020 18:10:43 -0700
|
||||||
|
Subject: [PATCH] Remove streams from PairedQueue
|
||||||
|
|
||||||
|
We shouldn't be doing stream calls just to see if the queue is
|
||||||
|
empty. This creates loads of garbage thanks to how often it's called.
|
||||||
|
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/PairedQueue.java b/src/main/java/net/minecraft/server/PairedQueue.java
|
||||||
|
index 85bb22e4b..2369afb4f 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/PairedQueue.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/PairedQueue.java
|
||||||
|
@@ -20,32 +20,30 @@ public interface PairedQueue<T, F> {
|
||||||
|
|
||||||
|
public static final class a implements PairedQueue<PairedQueue.b, Runnable> {
|
||||||
|
|
||||||
|
- private final List<Queue<Runnable>> a;
|
||||||
|
+ private final List<Queue<Runnable>> a; private final List<Queue<Runnable>> getQueues() { return this.a; } // Paper - OBFHELPER
|
||||||
|
|
||||||
|
public a(int i) {
|
||||||
|
- this.a = (List) IntStream.range(0, i).mapToObj((j) -> {
|
||||||
|
- return Queues.newConcurrentLinkedQueue();
|
||||||
|
- }).collect(Collectors.toList());
|
||||||
|
+ // Paper start - remove streams
|
||||||
|
+ this.a = new java.util.ArrayList<>(i); // queues
|
||||||
|
+ for (int j = 0; j < i; ++j) {
|
||||||
|
+ this.getQueues().add(Queues.newConcurrentLinkedQueue());
|
||||||
|
+ }
|
||||||
|
+ // Paper end - remove streams
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Runnable a() {
|
||||||
|
- Iterator iterator = this.a.iterator();
|
||||||
|
-
|
||||||
|
- Runnable runnable;
|
||||||
|
-
|
||||||
|
- do {
|
||||||
|
- if (!iterator.hasNext()) {
|
||||||
|
- return null;
|
||||||
|
+ // Paper start - remove iterator creation
|
||||||
|
+ for (int i = 0, len = this.getQueues().size(); i < len; ++i) {
|
||||||
|
+ Queue<Runnable> queue = this.getQueues().get(i);
|
||||||
|
+ Runnable ret = queue.poll();
|
||||||
|
+ if (ret != null) {
|
||||||
|
+ return ret;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- Queue<Runnable> queue = (Queue) iterator.next();
|
||||||
|
-
|
||||||
|
- runnable = (Runnable) queue.poll();
|
||||||
|
- } while (runnable == null);
|
||||||
|
-
|
||||||
|
- return runnable;
|
||||||
|
+ }
|
||||||
|
+ return null;
|
||||||
|
+ // Paper end - remove iterator creation
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean a(PairedQueue.b pairedqueue_b) {
|
||||||
|
@@ -57,7 +55,16 @@ public interface PairedQueue<T, F> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean b() {
|
||||||
|
- return this.a.stream().allMatch(Collection::isEmpty);
|
||||||
|
+ // Paper start - remove streams
|
||||||
|
+ // why are we doing streams every time we might want to execute a task?
|
||||||
|
+ for (int i = 0, len = this.getQueues().size(); i < len; ++i) {
|
||||||
|
+ Queue<Runnable> queue = this.getQueues().get(i);
|
||||||
|
+ if (!queue.isEmpty()) {
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return true;
|
||||||
|
+ // Paper end - remove streams
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
From 87074d6a3aa62c6ef3c61aff82bb869568066b5c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Spottedleaf <spottedleaf@spottedleaf.dev>
|
||||||
|
Date: Mon, 6 Apr 2020 18:06:24 -0700
|
||||||
|
Subject: [PATCH] Remove streams from MinecraftKey
|
||||||
|
|
||||||
|
They produce a lot of garbage.
|
||||||
|
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/MinecraftKey.java b/src/main/java/net/minecraft/server/MinecraftKey.java
|
||||||
|
index 2b271d3e5..b1beebf0e 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/MinecraftKey.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/MinecraftKey.java
|
||||||
|
@@ -125,15 +125,29 @@ public class MinecraftKey implements Comparable<MinecraftKey> {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean c(String s) {
|
||||||
|
- return s.chars().allMatch((i) -> {
|
||||||
|
- return i == 95 || i == 45 || i >= 97 && i <= 122 || i >= 48 && i <= 57 || i == 47 || i == 46;
|
||||||
|
- });
|
||||||
|
+ // Paper start - remove streams
|
||||||
|
+ for (int index = 0, len = s.length(); index < len; ++index) {
|
||||||
|
+ int i = (int)s.charAt(index);
|
||||||
|
+ boolean condition = i == 95 || i == 45 || i >= 97 && i <= 122 || i >= 48 && i <= 57 || i == 47 || i == 46; // this is copied from the replaced code.
|
||||||
|
+ if (!condition) {
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return true;
|
||||||
|
+ // Paper end - remove streams
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean d(String s) {
|
||||||
|
- return s.chars().allMatch((i) -> {
|
||||||
|
- return i == 95 || i == 45 || i >= 97 && i <= 122 || i >= 48 && i <= 57 || i == 46;
|
||||||
|
- });
|
||||||
|
+ // Paper start - remove streams
|
||||||
|
+ for (int index = 0, len = s.length(); index < len; ++index) {
|
||||||
|
+ int i = (int)s.charAt(index);
|
||||||
|
+ boolean condition = i == 95 || i == 45 || i >= 97 && i <= 122 || i >= 48 && i <= 57 || i == 46; // this is copied from the replaced code.
|
||||||
|
+ if (!condition) {
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return true;
|
||||||
|
+ // Paper end - remove streams
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class a implements JsonDeserializer<MinecraftKey>, JsonSerializer<MinecraftKey> {
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
From 1702763635d87ea03b05354b5e541cda6e348da0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Spottedleaf <spottedleaf@spottedleaf.dev>
|
||||||
|
Date: Mon, 6 Apr 2020 17:39:25 -0700
|
||||||
|
Subject: [PATCH] Reduce memory footprint of NBTTagCompound
|
||||||
|
|
||||||
|
Fastutil maps are going to have a lower memory footprint - which
|
||||||
|
is important because we clone chunk data after reading it for safety.
|
||||||
|
So, reduce the impact of the clone on GC.
|
||||||
|
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/NBTTagCompound.java b/src/main/java/net/minecraft/server/NBTTagCompound.java
|
||||||
|
index 98deaba12..02a2ed1ba 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/NBTTagCompound.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/NBTTagCompound.java
|
||||||
|
@@ -31,7 +31,7 @@ public class NBTTagCompound implements NBTBase {
|
||||||
|
if (i > 512) {
|
||||||
|
throw new RuntimeException("Tried to read NBT tag with too high complexity, depth > 512");
|
||||||
|
} else {
|
||||||
|
- HashMap hashmap = Maps.newHashMap();
|
||||||
|
+ it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<String, NBTBase> hashmap = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(8, 0.8f); // Paper - reduce memory footprint of NBTTagCompound
|
||||||
|
|
||||||
|
byte b0;
|
||||||
|
|
||||||
|
@@ -67,7 +67,7 @@ public class NBTTagCompound implements NBTBase {
|
||||||
|
}
|
||||||
|
|
||||||
|
public NBTTagCompound() {
|
||||||
|
- this(Maps.newHashMap());
|
||||||
|
+ this(new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(8, 0.8f)); // Paper - reduce memory footprint of NBTTagCompound
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@@ -402,9 +402,17 @@ public class NBTTagCompound implements NBTBase {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NBTTagCompound clone() {
|
||||||
|
- Map<String, NBTBase> map = Maps.newHashMap(Maps.transformValues(this.map, NBTBase::clone));
|
||||||
|
+ // Paper start - reduce memory footprint of NBTTagCompound
|
||||||
|
+ it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<String, NBTBase> ret = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(this.map.size(), 0.8f);
|
||||||
|
|
||||||
|
- return new NBTTagCompound(map);
|
||||||
|
+ Iterator<Map.Entry<String, NBTBase>> iterator = (this.map instanceof it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap) ? ((it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap)this.map).object2ObjectEntrySet().fastIterator() : this.map.entrySet().iterator();
|
||||||
|
+ while (iterator.hasNext()) {
|
||||||
|
+ Map.Entry<String, NBTBase> entry = iterator.next();
|
||||||
|
+ ret.put(entry.getKey(), entry.getValue().clone());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return new NBTTagCompound(ret);
|
||||||
|
+ // Paper end - reduce memory footprint of NBTTagCompound
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object object) {
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
Loading…
Reference in a new issue