diff --git a/src/main/java/codechicken/nei/recipe/GuiCraftingRecipe.java b/src/main/java/codechicken/nei/recipe/GuiCraftingRecipe.java index 1425c95ec..026f7eedb 100644 --- a/src/main/java/codechicken/nei/recipe/GuiCraftingRecipe.java +++ b/src/main/java/codechicken/nei/recipe/GuiCraftingRecipe.java @@ -34,7 +34,9 @@ public static GuiRecipe createRecipeGui(String outputId, boolean open, Object final BookmarkRecipeId recipeId; if ("item".equals(outputId)) { - results = Arrays.asList(results).stream().map(rslt -> normalizeItemStack((ItemStack) rslt)).toArray(); + for (int i = 0; i < results.length; i++) { + results[i] = normalizeItemStack((ItemStack) results[i]); + } recipeId = getRecipeId(mc.currentScreen, (ItemStack) results[0]); } else if ("recipeId".equals(outputId)) { recipeId = (BookmarkRecipeId) results[1]; @@ -103,7 +105,7 @@ public static ArrayList getCraftingHandlers(String outputId, O "outputId: " + outputId, "results: " + Arrays.toString(results)); - return recipeQuery.runWithProfiling("recipe.concurrent.crafting"); + return recipeQuery.runWithProfiling(NEIClientUtils.translate("recipe.concurrent.crafting")); } private static ArrayList filterByHandlerName(ArrayList craftinghandlers, diff --git a/src/main/java/codechicken/nei/recipe/GuiUsageRecipe.java b/src/main/java/codechicken/nei/recipe/GuiUsageRecipe.java index 4453980b0..46225a602 100644 --- a/src/main/java/codechicken/nei/recipe/GuiUsageRecipe.java +++ b/src/main/java/codechicken/nei/recipe/GuiUsageRecipe.java @@ -18,8 +18,9 @@ public class GuiUsageRecipe extends GuiRecipe { public static boolean openRecipeGui(String inputId, Object... ingredients) { if ("item".equals(inputId)) { - ingredients = Arrays.asList(ingredients).stream().map(ingr -> normalizeItemStack((ItemStack) ingr)) - .toArray(); + for (int i = 0; i < ingredients.length; i++) { + ingredients[i] = normalizeItemStack((ItemStack) ingredients[i]); + } } final ArrayList handlers = getUsageHandlers(inputId, ingredients); @@ -52,7 +53,7 @@ public static ArrayList getUsageHandlers(String inputId, Object.. "inputId: " + inputId, "ingredients: " + Arrays.toString(ingredients)); - return recipeQuery.runWithProfiling("recipe.concurrent.usage"); + return recipeQuery.runWithProfiling(NEIClientUtils.translate("recipe.concurrent.usage")); } private static ItemStack normalizeItemStack(ItemStack stack) { diff --git a/src/main/java/codechicken/nei/recipe/ItemsHistoryHandler.java b/src/main/java/codechicken/nei/recipe/ItemsHistoryHandler.java index 02ad0ac7c..d92b45a54 100644 --- a/src/main/java/codechicken/nei/recipe/ItemsHistoryHandler.java +++ b/src/main/java/codechicken/nei/recipe/ItemsHistoryHandler.java @@ -81,7 +81,7 @@ public boolean mouseClicked(GuiRecipe gui, int button, int recipe) { @Override public String getRecipeName() { - return null; + return "Items History"; } @Override diff --git a/src/main/java/codechicken/nei/recipe/ProfilerRecipeHandler.java b/src/main/java/codechicken/nei/recipe/ProfilerRecipeHandler.java index 4bab4e2e0..451c66804 100644 --- a/src/main/java/codechicken/nei/recipe/ProfilerRecipeHandler.java +++ b/src/main/java/codechicken/nei/recipe/ProfilerRecipeHandler.java @@ -3,29 +3,26 @@ import static codechicken.lib.gui.GuiDraw.drawString; import static codechicken.lib.gui.GuiDraw.getStringWidth; -import java.text.DecimalFormat; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.inventory.Container; import net.minecraft.item.ItemStack; -import codechicken.core.TaskProfiler; import codechicken.core.TaskProfiler.ProfilerResult; import codechicken.nei.NEIClientConfig; import codechicken.nei.NEIClientUtils; import codechicken.nei.PositionedStack; import codechicken.nei.api.IOverlayHandler; import codechicken.nei.api.IRecipeOverlayRenderer; +import codechicken.nei.util.AsyncTaskProfiler; public class ProfilerRecipeHandler implements ICraftingHandler, IUsageHandler { - private static final TaskProfiler profiler = new TaskProfiler(); + private static final AsyncTaskProfiler profiler = new AsyncTaskProfiler(); - public static TaskProfiler getProfiler() { - profiler.clear(); + public static AsyncTaskProfiler getProfiler() { return profiler; } @@ -55,8 +52,7 @@ public void drawBackground(int recipe) {} @Override public void drawForeground(int recipe) { List results = profiler.getResults(); - for (Iterator it = results.iterator(); it.hasNext();) - if (it.next().name.equals(getRecipeName())) it.remove(); + results.removeIf(profilerResult -> getRecipeName().equals(profilerResult.name)); results.sort((o1, o2) -> o1.time < o2.time ? 1 : -1); @@ -65,10 +61,9 @@ public void drawForeground(int recipe) { int y = (i % 6) * 20 + 6; drawString(r.name, 8, y, 0xFF808080, false); - DecimalFormat format = new DecimalFormat("0.00"); - String s = format.format(r.fraction * 100) + "%"; - if (r.time < 1000000L) s += " (" + (r.time / 1000) + "us)"; - else s += " (" + (r.time / 1000000) + "ms)"; + String s; + if (r.time < 1000000L) s = (r.time / 1000) + "us"; + else s = (r.time / 1000000) + "ms"; drawString(s, 156 - getStringWidth(s), y + 10, 0xFF404040, false); } diff --git a/src/main/java/codechicken/nei/recipe/RecipeHandlerQuery.java b/src/main/java/codechicken/nei/recipe/RecipeHandlerQuery.java index 122603c6b..66ac825c2 100644 --- a/src/main/java/codechicken/nei/recipe/RecipeHandlerQuery.java +++ b/src/main/java/codechicken/nei/recipe/RecipeHandlerQuery.java @@ -15,6 +15,7 @@ import codechicken.core.TaskProfiler; import codechicken.nei.ItemList; import codechicken.nei.NEIClientConfig; +import codechicken.nei.util.AsyncTaskProfiler; class RecipeHandlerQuery { @@ -34,6 +35,7 @@ class RecipeHandlerQuery { ArrayList runWithProfiling(String profilerSection) { TaskProfiler profiler = ProfilerRecipeHandler.getProfiler(); + profiler.clear(); profiler.start(profilerSection); try { ArrayList handlers = getRecipeHandlersParallel(); @@ -63,12 +65,17 @@ private ArrayList getRecipeHandlersParallel() throws InterruptedException, Ex private ArrayList getSerialHandlersWithRecipes() { return serialRecipeHandlers.stream().map(handler -> { + AsyncTaskProfiler profiler = ProfilerRecipeHandler.getProfiler(); + profiler.clearCurrent(); + profiler.start(handler.getRecipeName()); try { return isHidden(handler) ? null : recipeHandlerFunction.apply(handler); } catch (Throwable t) { printLog(t); error = true; return null; + } finally { + profiler.end(); } }).filter(h -> h != null && h.numRecipes() > 0 && SearchRecipeHandler.findFirst(h, (recipeIndex) -> true) != -1) .collect(Collectors.toCollection(ArrayList::new)); @@ -77,12 +84,17 @@ private ArrayList getSerialHandlersWithRecipes() { private ArrayList getHandlersWithRecipes() throws InterruptedException, ExecutionException { return ItemList.forkJoinPool.submit(() -> recipeHandlers.parallelStream().map(handler -> { + AsyncTaskProfiler profiler = ProfilerRecipeHandler.getProfiler(); + profiler.clearCurrent(); + profiler.start(handler.getRecipeName()); try { return isHidden(handler) ? null : recipeHandlerFunction.apply(handler); } catch (Throwable t) { printLog(t); error = true; return null; + } finally { + profiler.end(); } }).filter(h -> h != null && h.numRecipes() > 0 && SearchRecipeHandler.findFirst(h, (recipeIndex) -> true) != -1) .collect(Collectors.toCollection(ArrayList::new))).get(); diff --git a/src/main/java/codechicken/nei/util/AsyncTaskProfiler.java b/src/main/java/codechicken/nei/util/AsyncTaskProfiler.java new file mode 100644 index 000000000..97c84d9f5 --- /dev/null +++ b/src/main/java/codechicken/nei/util/AsyncTaskProfiler.java @@ -0,0 +1,47 @@ +package codechicken.nei.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; + +import codechicken.core.TaskProfiler; + +public class AsyncTaskProfiler extends TaskProfiler { + + public ThreadLocal threadedProfiler = ThreadLocal.withInitial(TaskProfiler::new); + + public Map times = new ConcurrentHashMap<>(); + + public void start(String section) { + if (section == null) section = ""; + threadedProfiler.get().start(section); + } + + public void end() { + threadedProfiler.get().end(); + times.putAll(threadedProfiler.get().times); + } + + @Override + public List getResults() { + ArrayList results = new ArrayList<>(times.size()); + long totalTime = times.values().stream().reduce(0L, Long::sum); + for (Entry e : times.entrySet()) + results.add(new ProfilerResult(e.getKey(), e.getValue(), totalTime)); + return results; + } + + @Override + public void clear() { + if (threadedProfiler.get().currentSection != null) threadedProfiler.get().end(); + threadedProfiler.get().clear(); + times.clear(); + } + + public void clearCurrent() { + if (threadedProfiler.get().currentSection != null) threadedProfiler.get().end(); + threadedProfiler.get().clear(); + } +} diff --git a/src/main/resources/assets/nei/lang/en_US.lang b/src/main/resources/assets/nei/lang/en_US.lang index 7fc5703c1..f24dd83cd 100644 --- a/src/main/resources/assets/nei/lang/en_US.lang +++ b/src/main/resources/assets/nei/lang/en_US.lang @@ -321,6 +321,8 @@ nei.recipe.firework.tooltip2=Multiple charges can be spawned from one rocket nei.recipe.brewing=Brewing nei.recipe.profiler.crafting=Crafting Profiling nei.recipe.profiler.usage=Usage Profiling +nei.recipe.concurrent.usage=Concurrent Usage - Total +nei.recipe.concurrent.crafting=Concurrent Crafting - Total nei.itemsort.minecraft=Minecraft nei.itemsort.minecraft.tip=Sorts items from vanilla minecraft first