From 966e25fa8d1c661eb08b8c5e3a4af9f3e8f82b89 Mon Sep 17 00:00:00 2001 From: nostalgic853 Date: Tue, 25 Oct 2022 00:58:00 +0800 Subject: [PATCH] Use optimized RecipeManager Original license: MIT Original project: https://github.com/fxmorin/carpet-fixes Optimized the RecipeManager getFirstMatch call to be up to 3x faster This is a fully vanilla optimization. Improves: [Blast]Furnace/Campfire/Smoker/Stonecutter/Crafting/Sheep Color Choosing This was mostly made for the auto crafting table, since the performance boost is much more visible while using that mod --- build-data/dev-imports.txt | 10 --- .../0027-Use-optimized-RecipeManager.patch | 84 +++++++++++++++++++ 2 files changed, 84 insertions(+), 10 deletions(-) delete mode 100644 build-data/dev-imports.txt create mode 100644 patches/server/0027-Use-optimized-RecipeManager.patch diff --git a/build-data/dev-imports.txt b/build-data/dev-imports.txt deleted file mode 100644 index f35428a..0000000 --- a/build-data/dev-imports.txt +++ /dev/null @@ -1,10 +0,0 @@ -# You can use this file to import files from minecraft libraries into the project -# format: -# -# both fully qualified and a file based syntax are accepted for : -# authlib com/mojang/authlib/yggdrasil/YggdrasilGameProfileRepository.java -# datafixerupper com.mojang.datafixers.DataFixerBuilder -# datafixerupper com/mojang/datafixers/util/Either.java -# To import classes from the vanilla Minecraft jar use `minecraft` as the artifactId: -# minecraft net.minecraft.world.level.entity.LevelEntityGetterAdapter -# minecraft net/minecraft/world/level/entity/LevelEntityGetter.java \ No newline at end of file diff --git a/patches/server/0027-Use-optimized-RecipeManager.patch b/patches/server/0027-Use-optimized-RecipeManager.patch new file mode 100644 index 0000000..0b73d2a --- /dev/null +++ b/patches/server/0027-Use-optimized-RecipeManager.patch @@ -0,0 +1,84 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: nostalgic853 +Date: Tue, 25 Oct 2022 00:57:45 +0800 +Subject: [PATCH] Use optimized RecipeManager + +Original license: MIT +Original project: https://github.com/fxmorin/carpet-fixes + +Optimized the RecipeManager getFirstMatch call to be up to 3x faster +This is a fully vanilla optimization. Improves: [Blast]Furnace/Campfire/Smoker/Stonecutter/Crafting/Sheep Color Choosing +This was mostly made for the auto crafting table, since the performance boost is much more visible while using that mod + +diff --git a/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java b/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java +index 4872f70977e73c889fe6e2339d00ebc64459613d..3e9cce51080addf294abab30532244628a9c63a2 100644 +--- a/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java ++++ b/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java +@@ -11,14 +11,7 @@ import com.google.gson.JsonParseException; + import com.google.gson.JsonSyntaxException; + import com.mojang.datafixers.util.Pair; + import com.mojang.logging.LogUtils; +-import java.util.Collection; +-import java.util.Collections; +-import java.util.Comparator; +-import java.util.Iterator; +-import java.util.List; +-import java.util.Map; + import java.util.Map.Entry; +-import java.util.Optional; + import java.util.stream.Collectors; + import java.util.stream.Stream; + import javax.annotation.Nullable; +@@ -33,6 +26,7 @@ import net.minecraft.world.Container; + import net.minecraft.world.item.ItemStack; + import net.minecraft.world.level.Level; + import org.slf4j.Logger; ++import java.util.*; // KeYi + + import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap; // CraftBukkit + +@@ -103,13 +97,28 @@ public class RecipeManager extends SimpleJsonResourceReloadListener { + } + + public > Optional getRecipeFor(RecipeType type, C inventory, Level world) { +- // CraftBukkit start +- Optional recipe = this.byType(type).values().stream().filter((irecipe) -> { +- return irecipe.matches(inventory, world); +- }).findFirst(); +- inventory.setCurrentRecipe(recipe.orElse(null)); // CraftBukkit - Clear recipe when no recipe is found +- // CraftBukkit end +- return recipe; ++ // KeYi start ++ int slots = 0; ++ int count; ++ //compare size to quickly remove recipes that are not even close. Plus remove streams ++ for (int slot = 0; slot < inventory.getContainerSize(); slot++) ++ if (!inventory.getItem(slot).isEmpty()) slots++; ++ for (Recipe recipe : this.getAllRecipesFor(type)) { ++ count = 0; ++ if (recipe instanceof CustomRecipe) { ++ if (recipe.matches(inventory, world)) { ++ return (Optional) Optional.of(recipe); ++ } ++ } else { ++ for (Ingredient ingredient : recipe.getIngredients()) ++ if (ingredient != Ingredient.EMPTY) count++; ++ if (count == slots && recipe.matches(inventory, world)) { ++ return (Optional) Optional.of(recipe); ++ } ++ } ++ } ++ return Optional.empty(); ++ // KeYi end + } + + public > Optional> getRecipeFor(RecipeType type, C inventory, Level world, @Nullable ResourceLocation id) { +@@ -131,7 +140,7 @@ public class RecipeManager extends SimpleJsonResourceReloadListener { + } + + public > List getAllRecipesFor(RecipeType type) { +- return List.copyOf(this.byType(type).values()); ++ return new ArrayList<>(this.getAllRecipesFor(type)); // KeYi + } + + public > List getRecipesFor(RecipeType type, C inventory, Level world) {