From fa411d8339e75f8e4127c07f42cab0563c14cf5b Mon Sep 17 00:00:00 2001 From: Glease <4586901+Glease@users.noreply.github.com> Date: Mon, 18 Oct 2021 16:21:21 +0800 Subject: Optimize away potentially expensive NBT copy in getAssociation --- src/main/java/gregtech/api/objects/GT_ItemStack.java | 7 ++++++- src/main/java/gregtech/api/util/GT_OreDictUnificator.java | 2 +- src/main/java/gregtech/api/util/GT_Recipe.java | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src/main/java/gregtech') diff --git a/src/main/java/gregtech/api/objects/GT_ItemStack.java b/src/main/java/gregtech/api/objects/GT_ItemStack.java index 7284854c5f..3e25454fa1 100644 --- a/src/main/java/gregtech/api/objects/GT_ItemStack.java +++ b/src/main/java/gregtech/api/objects/GT_ItemStack.java @@ -1,5 +1,6 @@ package gregtech.api.objects; +import gregtech.api.enums.GT_Values; import gregtech.api.util.GT_Utility; import net.minecraft.init.Items; import net.minecraft.item.Item; @@ -17,7 +18,11 @@ public class GT_ItemStack { } public GT_ItemStack(ItemStack aStack) { - this(aStack == null ? null : aStack.getItem(), aStack == null ? 0 : aStack.stackSize, aStack == null ? 0 : Items.feather.getDamage(aStack)); + this(aStack, false); + } + + public GT_ItemStack(ItemStack aStack, boolean wildcard) { + this(aStack == null ? null : aStack.getItem(), aStack == null ? 0 : aStack.stackSize, aStack == null ? 0 : wildcard ? GT_Values.W : Items.feather.getDamage(aStack)); } public GT_ItemStack(int aHashCode) { diff --git a/src/main/java/gregtech/api/util/GT_OreDictUnificator.java b/src/main/java/gregtech/api/util/GT_OreDictUnificator.java index 54ef5b2866..6e46517371 100644 --- a/src/main/java/gregtech/api/util/GT_OreDictUnificator.java +++ b/src/main/java/gregtech/api/util/GT_OreDictUnificator.java @@ -315,7 +315,7 @@ public class GT_OreDictUnificator { public static ItemData getItemData(ItemStack aStack) { if (GT_Utility.isStackInvalid(aStack)) return null; ItemData rData = sItemStack2DataMap.get(new GT_ItemStack(aStack)); - if (rData == null) rData = sItemStack2DataMap.get(new GT_ItemStack(GT_Utility.copyMetaData(W, aStack))); + if (rData == null) rData = sItemStack2DataMap.get(new GT_ItemStack(aStack, true)); return rData; } diff --git a/src/main/java/gregtech/api/util/GT_Recipe.java b/src/main/java/gregtech/api/util/GT_Recipe.java index bcd3c193de..6130adfaef 100644 --- a/src/main/java/gregtech/api/util/GT_Recipe.java +++ b/src/main/java/gregtech/api/util/GT_Recipe.java @@ -800,7 +800,7 @@ public class GT_Recipe implements Comparable { * @return if this Item is a valid Input for any for the Recipes */ public boolean containsInput(ItemStack aStack) { - return aStack != null && (mRecipeItemMap.containsKey(new GT_ItemStack(aStack)) || mRecipeItemMap.containsKey(new GT_ItemStack(GT_Utility.copyMetaData(W, aStack)))); + return aStack != null && (mRecipeItemMap.containsKey(new GT_ItemStack(aStack)) || mRecipeItemMap.containsKey(new GT_ItemStack(aStack, true))); } /** @@ -886,7 +886,7 @@ public class GT_Recipe implements Comparable { if (tRecipes != null) for (GT_Recipe tRecipe : tRecipes) if (!tRecipe.mFakeRecipe && tRecipe.isRecipeInputEqual(false, aDontCheckStackSizes, aFluids, aInputs)) return tRecipe.mEnabled && aVoltage * mAmperage >= tRecipe.mEUt ? tRecipe : null; - tRecipes = mRecipeItemMap.get(new GT_ItemStack(GT_Utility.copyMetaData(W, tStack))); + tRecipes = mRecipeItemMap.get(new GT_ItemStack(tStack, true)); if (tRecipes != null) for (GT_Recipe tRecipe : tRecipes) if (!tRecipe.mFakeRecipe && tRecipe.isRecipeInputEqual(false, aDontCheckStackSizes, aFluids, aInputs)) return tRecipe.mEnabled && aVoltage * mAmperage >= tRecipe.mEUt ? tRecipe : null; -- cgit From 4d91ffd264c10ba82d767403e200347c74b8338d Mon Sep 17 00:00:00 2001 From: Glease <4586901+Glease@users.noreply.github.com> Date: Mon, 18 Oct 2021 16:21:41 +0800 Subject: Cache sorted recipe list in NEI handlers --- src/main/java/gregtech/common/GT_Client.java | 7 +++ src/main/java/gregtech/common/GT_Proxy.java | 4 ++ .../java/gregtech/nei/GT_NEI_DefaultHandler.java | 56 +++++++++++----------- 3 files changed, 39 insertions(+), 28 deletions(-) (limited to 'src/main/java/gregtech') diff --git a/src/main/java/gregtech/common/GT_Client.java b/src/main/java/gregtech/common/GT_Client.java index 55efd20920..b9701bb451 100644 --- a/src/main/java/gregtech/common/GT_Client.java +++ b/src/main/java/gregtech/common/GT_Client.java @@ -152,6 +152,7 @@ public class GT_Client extends GT_Proxy private GT_ClientPreference mPreference; private boolean mFirstTick = false; public static final int ROTATION_MARKER_RESOLUTION = 120; + private int mReloadCount; public GT_Client() { mCapeRenderer = new GT_CapeRenderer(mCapeList); @@ -505,6 +506,12 @@ public class GT_Client extends GT_Proxy @SubscribeEvent public void onClientConnectedToServerEvent(FMLNetworkEvent.ClientConnectedToServerEvent aEvent) { mFirstTick = true; + mReloadCount++; + } + + @Override + public int getReloadCount() { + return mReloadCount; } @SubscribeEvent diff --git a/src/main/java/gregtech/common/GT_Proxy.java b/src/main/java/gregtech/common/GT_Proxy.java index ae95184062..2e18ea9693 100644 --- a/src/main/java/gregtech/common/GT_Proxy.java +++ b/src/main/java/gregtech/common/GT_Proxy.java @@ -776,6 +776,10 @@ public abstract class GT_Proxy implements IGT_Mod, IGuiHandler, IFuelHandler { public void onClientConnectedToServerEvent(FMLNetworkEvent.ClientConnectedToServerEvent aEvent) { } + public int getReloadCount() { + return 0; + } + @SubscribeEvent public void onArrowNockEvent(ArrowNockEvent aEvent) { if ((!aEvent.isCanceled()) && (GT_Utility.isStackValid(aEvent.result)) diff --git a/src/main/java/gregtech/nei/GT_NEI_DefaultHandler.java b/src/main/java/gregtech/nei/GT_NEI_DefaultHandler.java index f51acd9a77..f28c014bda 100644 --- a/src/main/java/gregtech/nei/GT_NEI_DefaultHandler.java +++ b/src/main/java/gregtech/nei/GT_NEI_DefaultHandler.java @@ -32,14 +32,18 @@ import net.minecraftforge.fluids.FluidStack; import org.lwjgl.opengl.GL11; import java.awt.*; +import java.lang.ref.SoftReference; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.stream.Collectors; public class GT_NEI_DefaultHandler extends RecipeMapHandler { public static final int sOffsetX = 5; public static final int sOffsetY = 11; + private int mCachedRecipesVersion = -1; + private SoftReference> mCachedRecipes = null; static { GuiContainerManager.addInputHandler(new GT_RectHandler()); @@ -51,12 +55,27 @@ public class GT_NEI_DefaultHandler extends RecipeMapHandler { this.transferRects.add(new TemplateRecipeHandler.RecipeTransferRect(new Rectangle(65, 13, 36, 18), getOverlayIdentifier())); } + @Deprecated public List getSortedRecipes() { List result = new ArrayList<>(this.mRecipeMap.mRecipeList); Collections.sort(result); return result; } + public List getCache() { + List cache; + if (mCachedRecipesVersion == GT_Mod.gregtechproxy.getReloadCount() || mCachedRecipes == null || (cache = mCachedRecipes.get()) == null) { + cache = mRecipeMap.mRecipeList.stream() // do not use parallel stream. This is already parallelized by NEI + .filter(r -> !r.mHidden) + .map(CachedDefaultRecipe::new) + .collect(Collectors.toList()); + // while the NEI parallelize handlers, for each individual handler it still uses sequential execution model + // so we do not need any synchronization here + mCachedRecipes = new SoftReference<>(cache); + } + return cache; + } + public static void drawText(int aX, int aY, String aString, int aColor) { Minecraft.getMinecraft().fontRenderer.drawString(aString, aX, aY, aColor); } @@ -69,11 +88,7 @@ public class GT_NEI_DefaultHandler extends RecipeMapHandler { @Override public void loadCraftingRecipes(String outputId, Object... results) { if (outputId.equals(getOverlayIdentifier())) { - for (GT_Recipe tRecipe : getSortedRecipes()) { - if (!tRecipe.mHidden) { - this.arecipes.add(new CachedDefaultRecipe(tRecipe)); - } - } + arecipes.addAll(getCache()); } else { super.loadCraftingRecipes(outputId, results); } @@ -83,7 +98,7 @@ public class GT_NEI_DefaultHandler extends RecipeMapHandler { public void loadCraftingRecipes(ItemStack aResult) { ItemData tPrefixMaterial = GT_OreDictUnificator.getAssociation(aResult); - ArrayList tResults = new ArrayList(); + ArrayList tResults = new ArrayList<>(); tResults.add(aResult); tResults.add(GT_OreDictUnificator.get(true, aResult)); if ((tPrefixMaterial != null) && (!tPrefixMaterial.mBlackListed) && (!tPrefixMaterial.mPrefix.mFamiliarPrefixes.isEmpty())) { @@ -101,16 +116,9 @@ public class GT_NEI_DefaultHandler extends RecipeMapHandler { if (tFluidStack != null) { tResults.addAll(GT_Utility.getContainersFromFluid(tFluidStack)); } - for (GT_Recipe tRecipe : getSortedRecipes()) { - if (!tRecipe.mHidden) { - CachedDefaultRecipe tNEIRecipe = new CachedDefaultRecipe(tRecipe); - for (ItemStack tStack : tResults) { - if (tNEIRecipe.contains(tNEIRecipe.mOutputs, tStack)) { - this.arecipes.add(tNEIRecipe); - break; - } - } - } + for (CachedDefaultRecipe recipe : getCache()) { + if (tResults.stream().anyMatch(stack -> recipe.contains(recipe.mOutputs, stack))) + arecipes.add(recipe); } } @@ -118,7 +126,7 @@ public class GT_NEI_DefaultHandler extends RecipeMapHandler { public void loadUsageRecipes(ItemStack aInput) { ItemData tPrefixMaterial = GT_OreDictUnificator.getAssociation(aInput); - ArrayList tInputs = new ArrayList(); + ArrayList tInputs = new ArrayList<>(); tInputs.add(aInput); tInputs.add(GT_OreDictUnificator.get(false, aInput)); if ((tPrefixMaterial != null) && (!tPrefixMaterial.mPrefix.mFamiliarPrefixes.isEmpty())) { @@ -136,18 +144,10 @@ public class GT_NEI_DefaultHandler extends RecipeMapHandler { if (tFluidStack != null) { tInputs.addAll(GT_Utility.getContainersFromFluid(tFluidStack)); } - for (GT_Recipe tRecipe : getSortedRecipes()) { - if (!tRecipe.mHidden) { - CachedDefaultRecipe tNEIRecipe = new CachedDefaultRecipe(tRecipe); - for (ItemStack tStack : tInputs) { - if (tNEIRecipe.contains(tNEIRecipe.mInputs, tStack)) { - this.arecipes.add(tNEIRecipe); - break; - } - } - } + for (CachedDefaultRecipe recipe : getCache()) { + if (tInputs.stream().anyMatch(stack -> recipe.contains(recipe.mInputs, stack))) + arecipes.add(recipe); } - CachedDefaultRecipe tNEIRecipe; } @Override -- cgit