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 2f712bfc1f717ba410bf34669d7b0a919ca218cc..fa7f4c3e14aa4ec11187f7c0f96cb4504ee38547 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.byType(type).values()) { + 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.byType(type).values()); // KeYi } public > List getRecipesFor(RecipeType type, C inventory, Level world) {