From 724f3baf4c8542d8ea7518b90321eb9434c1ef7e Mon Sep 17 00:00:00 2001 From: NotMyWing Date: Sun, 9 Jun 2024 13:33:33 +1100 Subject: [PATCH] Improve AESharedItemStack caching Reduces the item stack churn a little, improving overall server time taken from 6% to 2% on average --- .../appeng/util/item/AEItemStackRegistry.java | 35 +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/src/main/java/appeng/util/item/AEItemStackRegistry.java b/src/main/java/appeng/util/item/AEItemStackRegistry.java index 98ec97aa5dc..9243c713190 100644 --- a/src/main/java/appeng/util/item/AEItemStackRegistry.java +++ b/src/main/java/appeng/util/item/AEItemStackRegistry.java @@ -23,14 +23,16 @@ package appeng.util.item; +import com.google.common.collect.MapMaker; import net.minecraft.item.ItemStack; import javax.annotation.Nonnull; -import java.lang.ref.WeakReference; -import java.util.WeakHashMap; +import java.util.Map; public final class AEItemStackRegistry { - private static final WeakHashMap> REGISTRY = new WeakHashMap<>(); + + private static final ItemStackHashStrategy HASH_STRATEGY = ItemStackHashStrategy.comparingAllButCount(); + private static final Map REGISTRY = new MapMaker().weakValues().makeMap(); private AEItemStackRegistry() { } @@ -40,23 +42,18 @@ static synchronized AESharedItemStack getRegisteredStack(final @Nonnull ItemStac throw new IllegalArgumentException("stack cannot be empty"); } - int oldStackSize = itemStack.getCount(); - itemStack.setCount(1); - - AESharedItemStack search = new AESharedItemStack(itemStack); - WeakReference weak = REGISTRY.get(search); - AESharedItemStack ret = null; - - if (weak != null) { - ret = weak.get(); - } - - if (ret == null) { - ret = new AESharedItemStack(itemStack.copy()); - REGISTRY.put(ret, new WeakReference<>(ret)); + var hash = HASH_STRATEGY.hashCode(itemStack); + var ret = REGISTRY.get(hash); + if (ret != null) { + return ret; } - itemStack.setCount(oldStackSize); - return ret; + // computeIfAbsent is not feasible since new AESharedItemStack gets + // instantly GC'd when leaving the lambda. + var itemStackCopy = itemStack.copy(); + itemStackCopy.setCount(1); + var sharedStack = new AESharedItemStack(itemStackCopy); + REGISTRY.put(hash, sharedStack); + return sharedStack; } }