From bd9aa547d2a7d6e1cffa4dd65c16f91c13c925c3 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Wed, 15 Apr 2020 18:24:39 -0700 Subject: [PATCH] Optimise ArraySetSorted#removeIf Remove iterator allocation and ensure the call is always O(n) --- ...477-Optimise-ArraySetSorted-removeIf.patch | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 Spigot-Server-Patches/0477-Optimise-ArraySetSorted-removeIf.patch diff --git a/Spigot-Server-Patches/0477-Optimise-ArraySetSorted-removeIf.patch b/Spigot-Server-Patches/0477-Optimise-ArraySetSorted-removeIf.patch new file mode 100644 index 0000000000..20a78c77df --- /dev/null +++ b/Spigot-Server-Patches/0477-Optimise-ArraySetSorted-removeIf.patch @@ -0,0 +1,68 @@ +From f9c59df3e2db59fafe5e156b5c2e1929cc185218 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Wed, 15 Apr 2020 18:23:28 -0700 +Subject: [PATCH] Optimise ArraySetSorted#removeIf + +Remove iterator allocation and ensure the call is always O(n) + +diff --git a/src/main/java/net/minecraft/server/ArraySetSorted.java b/src/main/java/net/minecraft/server/ArraySetSorted.java +index 85f799a71..7db6b5850 100644 +--- a/src/main/java/net/minecraft/server/ArraySetSorted.java ++++ b/src/main/java/net/minecraft/server/ArraySetSorted.java +@@ -10,8 +10,8 @@ import java.util.NoSuchElementException; + public class ArraySetSorted extends AbstractSet { + + private final Comparator a; +- private T[] b; +- private int c; ++ private T[] b; private final T[] getBackingArray() { return this.b; } // Paper - OBFHELPER ++ private int c; private final int getSize() { return this.c; } private final void setSize(int value) { this.c = value; } // Paper - OBFHELPER + + private ArraySetSorted(int i, Comparator comparator) { + this.a = comparator; +@@ -22,6 +22,42 @@ public class ArraySetSorted extends AbstractSet { + } + } + ++ // Paper start - optimise removeIf ++ @Override ++ public boolean removeIf(java.util.function.Predicate filter) { ++ // prev. impl used an iterator, which could be n^2 and creates garbage ++ int i = 0, len = this.getSize(); ++ T[] backingArray = this.getBackingArray(); ++ ++ for (;;) { ++ if (i >= len) { ++ return false; ++ } ++ if (!filter.test(backingArray[i])) { ++ ++i; ++ continue; ++ } ++ break; ++ } ++ ++ // we only want to write back to backingArray if we really need to ++ ++ int lastIndex = i; // this is where new elements are shifted to ++ ++ for (; i < len; ++i) { ++ T curr = backingArray[i]; ++ if (!filter.test(curr)) { // if test throws we're screwed ++ backingArray[lastIndex++] = curr; ++ } ++ } ++ ++ // cleanup end ++ Arrays.fill(backingArray, lastIndex, len, null); ++ this.setSize(lastIndex); ++ return true; ++ } ++ // Paper end - optimise removeIf ++ + public static > ArraySetSorted a(int i) { + return new ArraySetSorted<>(i, (Comparator)Comparator.naturalOrder()); // Paper - decompile fix + } +-- +2.26.0 +