From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Taiyou06 Date: Thu, 20 Feb 2025 15:37:39 +0100 Subject: [PATCH] Improve sorting in SortedArraySet Changes between 5% to 10% depending on the size of the array For size 16: ~5% improvement (735.589 ns vs 697.095 ns) For size 4096: ~10% improvement (1563.115 ns vs 1396.803 ns) diff --git a/net/minecraft/util/SortedArraySet.java b/net/minecraft/util/SortedArraySet.java index 62c643febe5d642f5741ac2dcec1606a844593be..e8bad6e1c0aeb67005661db6ed42f745554fa652 100644 --- a/net/minecraft/util/SortedArraySet.java +++ b/net/minecraft/util/SortedArraySet.java @@ -12,6 +12,7 @@ import net.minecraft.Util; public class SortedArraySet extends AbstractSet implements ca.spottedleaf.moonrise.patches.chunk_system.util.ChunkSystemSortedArraySet { // Paper - rewrite chunk system private static final int DEFAULT_INITIAL_CAPACITY = 10; private final Comparator comparator; + private final boolean isNaturalOrder; // Leaf - Improve sorting in SortedArraySet T[] contents; int size; @@ -93,6 +94,7 @@ public class SortedArraySet extends AbstractSet implements ca.spottedleaf. private SortedArraySet(int initialCapacity, Comparator comparator) { this.comparator = comparator; + this.isNaturalOrder = comparator == Comparator.naturalOrder(); // Leaf - Improve sorting in SortedArraySet if (initialCapacity < 0) { throw new IllegalArgumentException("Initial capacity (" + initialCapacity + ") is negative"); } else { @@ -121,9 +123,57 @@ public class SortedArraySet extends AbstractSet implements ca.spottedleaf. } private int findIndex(T object) { - return Arrays.binarySearch(this.contents, 0, this.size, object, this.comparator); + // Leaf start - Improve sorting in SortedArraySet + return isNaturalOrder ? naturalBinarySearch(object) : customBinarySearch(object); } + private int naturalBinarySearch(T object) { + int low = 0; + int high = this.size - 1; + final Comparable key = (Comparable) object; + final T[] a = this.contents; + + while (low <= high) { + int mid = (low + high) >>> 1; + T midVal = a[mid]; + int cmp = key.compareTo(midVal); + + if (cmp < 0) { + high = mid - 1; + } else if (cmp > 0) { + low = mid + 1; + } else { + return mid; + } + } + + return -(low + 1); + } + + private int customBinarySearch(T object) { + int low = 0; + int high = this.size - 1; + final T[] a = this.contents; + final Comparator c = this.comparator; + + while (low <= high) { + int mid = (low + high) >>> 1; + T midVal = a[mid]; + int cmp = c.compare(midVal, object); + + if (cmp < 0) { + low = mid + 1; + } else if (cmp > 0) { + high = mid - 1; + } else { + return mid; + } + } + + return -(low + 1); + } + // Leaf end - Improve sorting in SortedArraySet + private static int getInsertionPosition(int index) { return -index - 1; }