mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-19 15:09:25 +00:00
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
|
|
}
|
|
}
|