mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-26 18:39:23 +00:00
ClassInstanceMultiMap belongs to Minecraft vanilla entity storage. And is unused, since replaced by spottedleaf's entity storage (rewrite chunk system). However these patches might be useful for vanilla entity storage if is used.
178 lines
7.7 KiB
Diff
178 lines
7.7 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Taiyou06 <kaandindar21@gmail.com>
|
|
Date: Fri, 21 Feb 2025 18:05:09 +0100
|
|
Subject: [PATCH] Optimize LinearPalette
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
getSerializedSize is 76% faster: 70.3ns → 17.2ns
|
|
getSerializedSize.write is 13-21% faster: 659.5ns → 523.1ns
|
|
|
|
diff --git a/net/minecraft/world/level/chunk/LinearPalette.java b/net/minecraft/world/level/chunk/LinearPalette.java
|
|
index 2073f6ff41aa570102621d183ee890b076267d54..2595ab14e2edd9c0f113f8997b0d3290a2c2fcad 100644
|
|
--- a/net/minecraft/world/level/chunk/LinearPalette.java
|
|
+++ b/net/minecraft/world/level/chunk/LinearPalette.java
|
|
@@ -10,6 +10,10 @@ import org.apache.commons.lang3.Validate;
|
|
public class LinearPalette<T> implements Palette<T>, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette<T> { // Paper - optimise palette reads
|
|
private final IdMap<T> registry;
|
|
private final T[] values;
|
|
+ // Leaf start - Optimize LinearPalette
|
|
+ private final int[] byteSizes;
|
|
+ private final int[] idCache; // Cached registry IDs for values
|
|
+ // Leaf end - Optimize LinearPalette
|
|
private final PaletteResize<T> resizeHandler;
|
|
private final int bits;
|
|
private int size;
|
|
@@ -24,23 +28,40 @@ public class LinearPalette<T> implements Palette<T>, ca.spottedleaf.moonrise.pat
|
|
private LinearPalette(IdMap<T> registry, int bits, PaletteResize<T> resizeHandler, List<T> values) {
|
|
this.registry = registry;
|
|
this.values = (T[])(new Object[1 << bits]);
|
|
+ // Leaf start - Optimize LinearPalette
|
|
+ this.idCache = new int[1 << bits];
|
|
+ this.byteSizes = new int[1 << bits]; // Initialize byteSizes
|
|
+ // Leaf end - Optimize LinearPalette
|
|
this.bits = bits;
|
|
this.resizeHandler = resizeHandler;
|
|
Validate.isTrue(values.size() <= this.values.length, "Can't initialize LinearPalette of size %d with %d entries", this.values.length, values.size());
|
|
|
|
for (int i = 0; i < values.size(); i++) {
|
|
- this.values[i] = values.get(i);
|
|
+ // Leaf start - Optimize LinearPalette
|
|
+ T value = values.get(i);
|
|
+ this.values[i] = value;
|
|
+ int id = registry.getId(value);
|
|
+ this.idCache[i] = id;
|
|
+ this.byteSizes[i] = VarInt.getByteSize(id); // Precompute byte size
|
|
+ // Leaf end - Optimize LinearPalette
|
|
}
|
|
|
|
this.size = values.size();
|
|
}
|
|
|
|
- private LinearPalette(IdMap<T> registry, T[] values, PaletteResize<T> resizeHandler, int bits, int size) {
|
|
+ private LinearPalette(IdMap<T> registry, T[] values, int[] idCache, PaletteResize<T> resizeHandler, int bits, int size) { // Leaf - Optimize LinearPalette
|
|
this.registry = registry;
|
|
this.values = values;
|
|
+ this.idCache = idCache; // Leaf - Optimize LinearPalette
|
|
this.resizeHandler = resizeHandler;
|
|
this.bits = bits;
|
|
this.size = size;
|
|
+ // Leaf start - Optimize LinearPalette
|
|
+ this.byteSizes = new int[idCache.length];
|
|
+ for (int i = 0; i < idCache.length; i++) {
|
|
+ this.byteSizes[i] = VarInt.getByteSize(idCache[i]);
|
|
+ }
|
|
+ // Leaf end - Optimize LinearPalette
|
|
}
|
|
|
|
public static <A> Palette<A> create(int bits, IdMap<A> registry, PaletteResize<A> resizeHandler, List<A> values) {
|
|
@@ -58,6 +79,11 @@ public class LinearPalette<T> implements Palette<T>, ca.spottedleaf.moonrise.pat
|
|
int ix = this.size;
|
|
if (ix < this.values.length) {
|
|
this.values[ix] = state;
|
|
+ // Leaf start - Optimize LinearPalette
|
|
+ int id = registry.getId(state);
|
|
+ this.idCache[ix] = id;
|
|
+ this.byteSizes[ix] = VarInt.getByteSize(id); // Cache byte size
|
|
+ // Leaf end - Optimize LinearPalette
|
|
this.size++;
|
|
return ix;
|
|
} else {
|
|
@@ -90,7 +116,12 @@ public class LinearPalette<T> implements Palette<T>, ca.spottedleaf.moonrise.pat
|
|
this.size = buffer.readVarInt();
|
|
|
|
for (int i = 0; i < this.size; i++) {
|
|
- this.values[i] = this.registry.byIdOrThrow(buffer.readVarInt());
|
|
+ // Leaf start - Optimize LinearPalette
|
|
+ int id = buffer.readVarInt();
|
|
+ this.values[i] = this.registry.byIdOrThrow(id);
|
|
+ this.idCache[i] = id;
|
|
+ this.byteSizes[i] = VarInt.getByteSize(id); // Precompute during read
|
|
+ // Leaf end - Optimize LinearPalette
|
|
}
|
|
}
|
|
|
|
@@ -99,17 +130,18 @@ public class LinearPalette<T> implements Palette<T>, ca.spottedleaf.moonrise.pat
|
|
buffer.writeVarInt(this.size);
|
|
|
|
for (int i = 0; i < this.size; i++) {
|
|
- buffer.writeVarInt(this.registry.getId(this.values[i]));
|
|
+ buffer.writeVarInt(this.idCache[i]); // Leaf - Optimize LinearPalette - Use cached ID
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public int getSerializedSize() {
|
|
- int byteSize = VarInt.getByteSize(this.getSize());
|
|
-
|
|
- for (int i = 0; i < this.getSize(); i++) {
|
|
- byteSize += VarInt.getByteSize(this.registry.getId(this.values[i]));
|
|
+ // Leaf start - Optimize LinearPalette
|
|
+ int byteSize = VarInt.getByteSize(this.size);
|
|
+ for (int i = 0; i < this.size; i++) {
|
|
+ byteSize += this.byteSizes[i]; // Use cached byte sizes
|
|
}
|
|
+ // Leaf end - Optimize LinearPalette
|
|
|
|
return byteSize;
|
|
}
|
|
@@ -121,6 +153,56 @@ public class LinearPalette<T> implements Palette<T>, ca.spottedleaf.moonrise.pat
|
|
|
|
@Override
|
|
public Palette<T> copy(PaletteResize<T> resizeHandler) {
|
|
- return new LinearPalette<>(this.registry, (T[])((Object[])this.values.clone()), resizeHandler, this.bits, this.size);
|
|
+ // Leaf start - Optimize LinearPalette
|
|
+ // Special case for empty palette - fastest possible return
|
|
+ if (this.size == 0) {
|
|
+ return new LinearPalette<>(this.registry, (T[]) new Object[1], new int[1], resizeHandler, this.bits, 0);
|
|
+ }
|
|
+
|
|
+ // For small sizes, allocate exact-sized arrays and use direct assignment
|
|
+ if (this.size <= 4) {
|
|
+ @SuppressWarnings("unchecked")
|
|
+ T[] valuesCopy = (T[]) new Object[this.size];
|
|
+ int[] idCacheCopy = new int[this.size];
|
|
+
|
|
+ // Unrolled loop eliminates loop overhead for small arrays
|
|
+ switch (this.size) {
|
|
+ case 4:
|
|
+ valuesCopy[3] = this.values[3];
|
|
+ idCacheCopy[3] = this.idCache[3];
|
|
+ // Fall through
|
|
+ case 3:
|
|
+ valuesCopy[2] = this.values[2];
|
|
+ idCacheCopy[2] = this.idCache[2];
|
|
+ // Fall through
|
|
+ case 2:
|
|
+ valuesCopy[1] = this.values[1];
|
|
+ idCacheCopy[1] = this.idCache[1];
|
|
+ // Fall through
|
|
+ case 1:
|
|
+ valuesCopy[0] = this.values[0];
|
|
+ idCacheCopy[0] = this.idCache[0];
|
|
+ }
|
|
+
|
|
+ return new LinearPalette<>(this.registry, valuesCopy, idCacheCopy, resizeHandler, this.bits, this.size);
|
|
+ }
|
|
+
|
|
+ // For larger arrays, use optimized bulk operations
|
|
+ @SuppressWarnings("unchecked")
|
|
+ T[] valuesCopy = (T[]) new Object[this.size];
|
|
+ int[] idCacheCopy = new int[this.size];
|
|
+
|
|
+ System.arraycopy(this.values, 0, valuesCopy, 0, this.size);
|
|
+ System.arraycopy(this.idCache, 0, idCacheCopy, 0, this.size);
|
|
+
|
|
+ return new LinearPalette<>(
|
|
+ this.registry,
|
|
+ valuesCopy,
|
|
+ idCacheCopy,
|
|
+ resizeHandler,
|
|
+ this.bits,
|
|
+ this.size
|
|
+ );
|
|
+ // Leaf end - Optimize LinearPalette
|
|
}
|
|
}
|