9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2026-01-04 15:41:40 +00:00

Update reduce array allocations

This commit is contained in:
Dreeam
2025-07-25 10:22:55 +08:00
parent 006fe7ce3a
commit ffa437b4aa
4 changed files with 172 additions and 220 deletions

View File

@@ -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