mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-26 18:39:23 +00:00
Update reduce array allocations
This commit is contained in:
@@ -6,6 +6,18 @@ Subject: [PATCH] Reduce array allocations
|
||||
License: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
Gale - https://galemc.org
|
||||
|
||||
Enum's values returns anew array copy of the enums, this behavior is defined in
|
||||
`src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java#visitEnumDef`
|
||||
|
||||
This is a defensive programming strategy to prevent enums from being modified. However,
|
||||
copying is unnecessary if we only have read calls.
|
||||
So we can cache the values result to avoid useless allocations.
|
||||
|
||||
Cached as the array since it does not create iterator on the enhanced for loop,
|
||||
But the list does, and may spend more time than iterating using the array.
|
||||
|
||||
The JMH benchmark of this patch can be found in SunBox's `CachedEnumValuesForLoop`
|
||||
|
||||
This patch is based on the following patch:
|
||||
"reduce allocs"
|
||||
By: Simon Gardling <titaniumtown@gmail.com>
|
||||
@@ -250,7 +262,7 @@ index 0e44397c9d53ff30a96c9e8e392a363fa9ae0c55..dbf31389f0e9796c80afbffddf6a20cb
|
||||
private final EquipmentSlot.Type type;
|
||||
private final int index;
|
||||
diff --git a/net/minecraft/world/entity/EquipmentSlotGroup.java b/net/minecraft/world/entity/EquipmentSlotGroup.java
|
||||
index 381e0a1c0af7e339713ed1df1c2f21121c1bbd0f..1ebcab2ee9898a618ad76b18491be19859629192 100644
|
||||
index 381e0a1c0af7e339713ed1df1c2f21121c1bbd0f..4e847c3f9d761da5dda11dec60582d9d9e630b37 100644
|
||||
--- a/net/minecraft/world/entity/EquipmentSlotGroup.java
|
||||
+++ b/net/minecraft/world/entity/EquipmentSlotGroup.java
|
||||
@@ -24,6 +24,7 @@ public enum EquipmentSlotGroup implements StringRepresentable, Iterable<Equipmen
|
||||
@@ -261,15 +273,6 @@ index 381e0a1c0af7e339713ed1df1c2f21121c1bbd0f..1ebcab2ee9898a618ad76b18491be198
|
||||
public static final IntFunction<EquipmentSlotGroup> BY_ID = ByIdMap.continuous(
|
||||
equipmentSlotGroup -> equipmentSlotGroup.id, values(), ByIdMap.OutOfBoundsStrategy.ZERO
|
||||
);
|
||||
@@ -38,7 +39,7 @@ public enum EquipmentSlotGroup implements StringRepresentable, Iterable<Equipmen
|
||||
this.id = id;
|
||||
this.key = key;
|
||||
this.predicate = predicate;
|
||||
- this.slots = EquipmentSlot.VALUES.stream().filter(predicate).toList();
|
||||
+ this.slots = EquipmentSlot.VALUES.stream().filter(predicate).toList(); // Gale - JettPack - reduce array allocations
|
||||
}
|
||||
|
||||
private EquipmentSlotGroup(final int id, final String key, final EquipmentSlot slot) {
|
||||
diff --git a/net/minecraft/world/entity/EquipmentTable.java b/net/minecraft/world/entity/EquipmentTable.java
|
||||
index b383836c200ca9f7bd84639367aa81b57868fb25..3af4a6dcc81afaf2860325fe5852c9a941f216d4 100644
|
||||
--- a/net/minecraft/world/entity/EquipmentTable.java
|
||||
@@ -283,6 +286,112 @@ index b383836c200ca9f7bd84639367aa81b57868fb25..3af4a6dcc81afaf2860325fe5852c9a9
|
||||
}
|
||||
|
||||
private static Map<EquipmentSlot, Float> createForAllSlots(List<EquipmentSlot> equipmentSlots, float dropChance) {
|
||||
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
||||
index 395ebf0a5fa14d9ff43b2d2e8e63aeaaf4612443..c6f87ee9b7c2b0bfc2d459a86b60ad2eaa23b594 100644
|
||||
--- a/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -3358,7 +3358,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
Map<org.bukkit.inventory.EquipmentSlot, io.papermc.paper.event.entity.EntityEquipmentChangedEvent.EquipmentChange> equipmentChanges = null;
|
||||
// Paper end - EntityEquipmentChangedEvent
|
||||
|
||||
- for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES) {
|
||||
+ for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES_ARRAY) { // Gale - JettPack - reduce array allocations
|
||||
ItemStack itemStack = this.lastEquipmentItems.get(equipmentSlot);
|
||||
ItemStack itemBySlot = this.getItemBySlot(equipmentSlot);
|
||||
if (this.equipmentHasChanged(itemStack, itemBySlot)) {
|
||||
@@ -3630,7 +3630,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
|
||||
public boolean canGlide() {
|
||||
if (!this.onGround() && !this.isPassenger() && !this.hasEffect(MobEffects.LEVITATION)) {
|
||||
- for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES) {
|
||||
+ for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES_ARRAY) { // Gale - JettPack - reduce array allocations
|
||||
if (canGlideUsing(this.getItemBySlot(equipmentSlot), equipmentSlot)) {
|
||||
return true;
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java
|
||||
index 4d4b58b684ca115f4d8f672362d4c8252ef9481a..939d8c53a8eb445c1b5b0c65842ecb64ad317252 100644
|
||||
--- a/net/minecraft/world/entity/Mob.java
|
||||
+++ b/net/minecraft/world/entity/Mob.java
|
||||
@@ -338,7 +338,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
||||
if (this.xpReward > 0) {
|
||||
int i = this.xpReward;
|
||||
|
||||
- for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES) {
|
||||
+ for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES_ARRAY) { // Gale - JettPack - reduce array allocations
|
||||
if (equipmentSlot.canIncreaseExperience()) {
|
||||
ItemStack itemBySlot = this.getItemBySlot(equipmentSlot);
|
||||
if (!itemBySlot.isEmpty() && this.dropChances.byEquipment(equipmentSlot) <= 1.0F) {
|
||||
@@ -950,7 +950,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
||||
protected void dropCustomDeathLoot(ServerLevel level, DamageSource damageSource, boolean recentlyHit) {
|
||||
super.dropCustomDeathLoot(level, damageSource, recentlyHit);
|
||||
|
||||
- for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES) {
|
||||
+ for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES_ARRAY) { // Gale - JettPack - reduce array allocations
|
||||
if (this.shouldSkipLoot(equipmentSlot)) continue; // Paper
|
||||
ItemStack itemBySlot = this.getItemBySlot(equipmentSlot);
|
||||
float f = this.dropChances.byEquipment(equipmentSlot);
|
||||
@@ -994,7 +994,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
||||
public Set<EquipmentSlot> dropPreservedEquipment(ServerLevel level, Predicate<ItemStack> filter) {
|
||||
Set<EquipmentSlot> set = new HashSet<>();
|
||||
|
||||
- for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES) {
|
||||
+ for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES_ARRAY) { // Gale - JettPack - reduce array allocations
|
||||
ItemStack itemBySlot = this.getItemBySlot(equipmentSlot);
|
||||
if (!itemBySlot.isEmpty()) {
|
||||
if (!filter.test(itemBySlot)) {
|
||||
@@ -1122,7 +1122,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
||||
protected void populateDefaultEquipmentEnchantments(ServerLevelAccessor level, RandomSource random, DifficultyInstance difficulty) {
|
||||
this.enchantSpawnedWeapon(level, random, difficulty);
|
||||
|
||||
- for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES) {
|
||||
+ for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES_ARRAY) { // Gale - JettPack - reduce array allocations
|
||||
if (equipmentSlot.getType() == EquipmentSlot.Type.HUMANOID_ARMOR) {
|
||||
this.enchantSpawnedArmor(level, random, equipmentSlot, difficulty);
|
||||
}
|
||||
@@ -1539,7 +1539,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
||||
protected void removeAfterChangingDimensions() {
|
||||
super.removeAfterChangingDimensions();
|
||||
|
||||
- for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES) {
|
||||
+ for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES_ARRAY) { // Gale - JettPack - reduce array allocations
|
||||
ItemStack itemBySlot = this.getItemBySlot(equipmentSlot);
|
||||
if (!itemBySlot.isEmpty()) {
|
||||
itemBySlot.setCount(0);
|
||||
diff --git a/net/minecraft/world/entity/decoration/ArmorStand.java b/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
index 5ee368580d878a3845349c3d50cc0dc549c42cab..9952e84dd94b8773c5ba8fcc4526e7714ebc2136 100644
|
||||
--- a/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -456,7 +456,7 @@ public class ArmorStand extends LivingEntity {
|
||||
this.playBrokenSound();
|
||||
// this.dropAllDeathLoot(level, damageSource); // CraftBukkit - moved down
|
||||
|
||||
- for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES) {
|
||||
+ for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES_ARRAY) { // Gale - JettPack - reduce array allocations
|
||||
ItemStack itemStack = this.equipment.get(equipmentSlot); // Paper - move equipment removal past event call
|
||||
if (!itemStack.isEmpty()) {
|
||||
this.drops.add(new DefaultDrop(itemStack, stack -> Block.popResource(this.level(), this.blockPosition().above(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior; mirror so we can destroy it later - though this call site was safe & spawn drops correctly}
|
||||
@@ -465,7 +465,7 @@ public class ArmorStand extends LivingEntity {
|
||||
// Paper start - move equipment removal past event call
|
||||
org.bukkit.event.entity.EntityDeathEvent event = this.dropAllDeathLoot(level, damageSource);
|
||||
if (!event.isCancelled()) {
|
||||
- for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES) {
|
||||
+ for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES_ARRAY) { // Gale - JettPack - reduce array allocations
|
||||
this.equipment.set(equipmentSlot, ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
|
||||
index e5e08dbefead90e9fe2bb05e4f0257f7aa4c0686..5160c349f1ace36d6de11f23e0f957f37fc19165 100644
|
||||
--- a/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/net/minecraft/world/entity/player/Player.java
|
||||
@@ -413,7 +413,7 @@ public abstract class Player extends LivingEntity {
|
||||
}
|
||||
|
||||
private boolean isEquipped(Item item) {
|
||||
- for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES) {
|
||||
+ for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES_ARRAY) { // Gale - JettPack - reduce array allocations
|
||||
ItemStack itemBySlot = this.getItemBySlot(equipmentSlot);
|
||||
Equippable equippable = itemBySlot.get(DataComponents.EQUIPPABLE);
|
||||
if (itemBySlot.is(item) && equippable != null && equippable.slot() == equipmentSlot) {
|
||||
diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java
|
||||
index da16f4831c875e07c25d7ed041bed493db614658..951c86278e8cb5cd801a5db2ebfabef8c6d813ef 100644
|
||||
--- a/net/minecraft/world/item/ItemStack.java
|
||||
@@ -309,6 +418,41 @@ index bfda76974ea8d4397e2c2ebf5bdcb5d7e5f0bab5..cabbc93409ca99180d115e2f23419ee1
|
||||
} else {
|
||||
String[] strings = new String[pattern.size() - i3 - i2];
|
||||
|
||||
diff --git a/net/minecraft/world/item/enchantment/Enchantment.java b/net/minecraft/world/item/enchantment/Enchantment.java
|
||||
index 7a620eb92b1e672cedd72ec4d986c01eba337686..0460da0124d2c48b7fed45fa182537fd8059135d 100644
|
||||
--- a/net/minecraft/world/item/enchantment/Enchantment.java
|
||||
+++ b/net/minecraft/world/item/enchantment/Enchantment.java
|
||||
@@ -109,7 +109,7 @@ public record Enchantment(Component description, Enchantment.EnchantmentDefiniti
|
||||
public Map<EquipmentSlot, ItemStack> getSlotItems(LivingEntity entity) {
|
||||
Map<EquipmentSlot, ItemStack> map = Maps.newEnumMap(EquipmentSlot.class);
|
||||
|
||||
- for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES) {
|
||||
+ for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES_ARRAY) { // Gale - JettPack - reduce array allocations
|
||||
if (this.matchingSlot(equipmentSlot)) {
|
||||
ItemStack itemBySlot = entity.getItemBySlot(equipmentSlot);
|
||||
if (!itemBySlot.isEmpty()) {
|
||||
diff --git a/net/minecraft/world/item/enchantment/EnchantmentHelper.java b/net/minecraft/world/item/enchantment/EnchantmentHelper.java
|
||||
index 66234431b265e0596275ca468cd40f8da98c22e2..b20415b47e209aedbc60ff17238e575dfe33849a 100644
|
||||
--- a/net/minecraft/world/item/enchantment/EnchantmentHelper.java
|
||||
+++ b/net/minecraft/world/item/enchantment/EnchantmentHelper.java
|
||||
@@ -153,7 +153,7 @@ public class EnchantmentHelper {
|
||||
}
|
||||
|
||||
private static void runIterationOnEquipment(LivingEntity entity, EnchantmentHelper.EnchantmentInSlotVisitor visitor) {
|
||||
- for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES) {
|
||||
+ for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES_ARRAY) { // Gale - JettPack - reduce array allocations
|
||||
runIterationOnItem(entity.getItemBySlot(equipmentSlot), equipmentSlot, entity, visitor);
|
||||
}
|
||||
}
|
||||
@@ -467,7 +467,7 @@ public class EnchantmentHelper {
|
||||
public static Optional<EnchantedItemInUse> getRandomItemWith(DataComponentType<?> componentType, LivingEntity entity, Predicate<ItemStack> filter) {
|
||||
List<EnchantedItemInUse> list = new ArrayList<>();
|
||||
|
||||
- for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES) {
|
||||
+ for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES_ARRAY) { // Gale - JettPack - reduce array allocations
|
||||
ItemStack itemBySlot = entity.getItemBySlot(equipmentSlot);
|
||||
if (filter.test(itemBySlot)) {
|
||||
ItemEnchantments itemEnchantments = itemBySlot.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY);
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index a0254e85fccebb66ce02bd58f9d461addd8ad73d..1f7b3db02e59c4cbc93bc0e4e42bd20e0031c4bd 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
|
||||
@@ -9,7 +9,7 @@ Gale - https://galemc.org
|
||||
The JMH benchmark of this patch can be found in SunBox's `RecordHashCode`
|
||||
|
||||
diff --git a/ca/spottedleaf/moonrise/patches/collisions/util/FluidOcclusionCacheKey.java b/ca/spottedleaf/moonrise/patches/collisions/util/FluidOcclusionCacheKey.java
|
||||
index cf9ffdeff6bf0b62a45f7a44dbfe0dd7d17dc4f4..f1480625eaece1553d4a96ec54138a463a6fc1ca 100644
|
||||
index cf9ffdeff6bf0b62a45f7a44dbfe0dd7d17dc4f4..fcff01c84d611a75dbf79b1644092516c7cfb0bc 100644
|
||||
--- a/ca/spottedleaf/moonrise/patches/collisions/util/FluidOcclusionCacheKey.java
|
||||
+++ b/ca/spottedleaf/moonrise/patches/collisions/util/FluidOcclusionCacheKey.java
|
||||
@@ -3,5 +3,58 @@ package ca.spottedleaf.moonrise.patches.collisions.util;
|
||||
@@ -17,7 +17,7 @@ index cf9ffdeff6bf0b62a45f7a44dbfe0dd7d17dc4f4..f1480625eaece1553d4a96ec54138a46
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
-public record FluidOcclusionCacheKey(BlockState first, BlockState second, Direction direction, boolean result) {
|
||||
+// Gale start - Lithium - cache FluidOcclusionCacheKey hash
|
||||
+// Gale start - cache FluidOcclusionCacheKey hash
|
||||
+public final class FluidOcclusionCacheKey {
|
||||
+ private final BlockState first;
|
||||
+ private final BlockState second;
|
||||
@@ -70,5 +70,5 @@ index cf9ffdeff6bf0b62a45f7a44dbfe0dd7d17dc4f4..f1480625eaece1553d4a96ec54138a46
|
||||
+ "direction=" + direction + ", " +
|
||||
+ "result=" + result + ']';
|
||||
+ }
|
||||
+ // Gale end - Lithium - cache FluidOcclusionCacheKey hash
|
||||
+ // Gale end - cache FluidOcclusionCacheKey hash
|
||||
}
|
||||
|
||||
@@ -6,6 +6,18 @@ Subject: [PATCH] Reduce array allocations
|
||||
License: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
Gale - https://galemc.org
|
||||
|
||||
Enum's values returns anew array copy of the enums, this behavior is defined in
|
||||
`src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java#visitEnumDef`
|
||||
|
||||
This is a defensive programming strategy to prevent enums from being modified. However,
|
||||
copying is unnecessary if we only have read calls.
|
||||
So we can cache the values result to avoid useless allocations.
|
||||
|
||||
Cached as the array since it does not create iterator on the enhanced for loop,
|
||||
But the list does, and may spend more time than iterating using the array.
|
||||
|
||||
The JMH benchmark of this patch can be found in SunBox's `CachedEnumValuesForLoop`
|
||||
|
||||
This patch is based on the following patch:
|
||||
"reduce allocs"
|
||||
By: Simon Gardling <titaniumtown@gmail.com>
|
||||
@@ -98,7 +110,7 @@ index db92261a6cb3758391108361096417c61bc82cdc..1a14fddb36ca3c14d243304db629d0c5
|
||||
|
||||
public SortedList(final E[] elements, final Comparator<? super E> comparator) {
|
||||
diff --git a/src/main/java/io/papermc/paper/command/brigadier/PaperCommands.java b/src/main/java/io/papermc/paper/command/brigadier/PaperCommands.java
|
||||
index af480008adc07c63344d625101d1bf42fab96b5d..8c9609b95cf27b6316c48a554b2c508aa527b964 100644
|
||||
index f37adc5dcad50a3e313c63ebee795161b4fa8b8f..948460266c6fd40b7b5197f81aa5ed90dc54b66a 100644
|
||||
--- a/src/main/java/io/papermc/paper/command/brigadier/PaperCommands.java
|
||||
+++ b/src/main/java/io/papermc/paper/command/brigadier/PaperCommands.java
|
||||
@@ -178,7 +178,7 @@ public class PaperCommands implements Commands, PaperRegistrar<LifecycleEventOwn
|
||||
@@ -124,7 +136,7 @@ index 58ca24715eafd1ac3cc9657b1cc235049d69bb59..acb764b71bb3e8f159a758002f7d1077
|
||||
return true;
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftEntityEquipment.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftEntityEquipment.java
|
||||
index 4abe58077fae4e68cceda9624fed013bca1d6f22..72aa906ccf64dd9be085728a897f323ab0822eba 100644
|
||||
index 4abe58077fae4e68cceda9624fed013bca1d6f22..dbbff2c73ae995f847b470a1e0853583cc377dc4 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftEntityEquipment.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftEntityEquipment.java
|
||||
@@ -165,7 +165,7 @@ public class CraftEntityEquipment implements EntityEquipment {
|
||||
@@ -132,7 +144,7 @@ index 4abe58077fae4e68cceda9624fed013bca1d6f22..72aa906ccf64dd9be085728a897f323a
|
||||
@Override
|
||||
public void clear() {
|
||||
- for (net.minecraft.world.entity.EquipmentSlot slot : net.minecraft.world.entity.EquipmentSlot.values()) {
|
||||
+ for (net.minecraft.world.entity.EquipmentSlot slot : net.minecraft.world.entity.EquipmentSlot.VALUES) { // Gale - JettPack - reduce array allocations
|
||||
+ for (net.minecraft.world.entity.EquipmentSlot slot : net.minecraft.world.entity.EquipmentSlot.VALUES_ARRAY) { // Gale - JettPack - reduce array allocations
|
||||
this.setEquipment(slot, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user