Applied Energistics 2

Applied Energistics 2

160M Downloads

Massive lag in CraftingTermMenu.findMissingIngredients() with JEI

andrewjbennett opened this issue ยท 6 comments

commented

How to reproduce the performance issue

I can only reproduce this when I have "ME DISK Drive"s from AE2Things. I suspect it's not about the drives themselves but the fact that they have a lot of items in them?

Steps to reproduce:

  1. Have (a lot of unique items? Specifically ME DISK Drives?) in your ME system
  2. Open any crafting terminal (wireless or wired; this only happens in crafting terminals and not pattern terminals etc)
  3. Click on some craftable recipe in JEI
  4. Mouse over a bunch of different recipes in JEI (not sure if necessary, but this substantially increases the lag)

What should happen:

Everything works normally, no lag

What actually happens:

My FPS drops severely to the point that the game is unplayable (I'd estimate <2 fps)


Note: if I remove the ME DISK Drives from my ME Drive, I can no longer reproduce the lag. I'll try to see if I can reproduce it by moving all of those items into normal ME item storage cells.

Spark profile link

https://spark.lucko.me/yIAHjvMSh1

Which minecraft version are you using?

1.19

On which mod loaders does it happen?

Forge

Additional details

Here's a profile of me doing the same thing with my ME DISK Drives removed: https://spark.lucko.me/2yitRAjvhm

Based on the profile I wonder if it might be related to items with complex NBT, but I've been trying to remove everything that might have complex NBT (e.g. I've already removed all weapons, armor, enchanted things, etc) and the problem still happens.

I'm using version 12.9.5, I can't find the function appeng.menu.me.items.CraftingTermMenu.hasIngredient() in the current codebase so maybe this is a bug which has already been fixed in the current versions?

commented

This looks like it might be similar to #7356, whose sparkc profile says they're running v15.0.9beta (vs my v12.9.5):

Their profile (relevant part):

image

My profile (relevant part):

image

commented

Ah, here's the code in the version that I'm running:

* Checks if the terminal has a given amount of the requested item. Used to determine for REI/JEI if a recipe is
* potentially craftable based on the available items.
* <p/>
* This method is <strong>slow</strong>, but it is client-only and thus doesn't scale with the player count.
*/
public boolean hasIngredient(Predicate<ItemStack> ingredient, int amount) {
var clientRepo = getClientRepo();
if (clientRepo != null) {
for (var stack : clientRepo.getAllEntries()) {
if (stack.getWhat() instanceof AEItemKey itemKey && ingredient.test(itemKey.toStack())) {
if (stack.getStoredAmount() >= amount) {
return true;
}
amount -= stack.getStoredAmount();
}
}
}

This method is slow, but it is client-only and thus doesn't scale with the player count.

commented

It looks like the code was added in this commit: f8d3db4 "Forge 1.19.3"

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

I'm not sure where specifically the hasIngredient function came from (other than being added in that commit), but I suspect at this point I should hand the investigation over to you (since you'll know your codebase and release process etc a lot better than me ๐Ÿ™‚ )

commented

I've been looking into this further and I'm still quite confused about where the code came from, I suspect it's likely something like a bunch of commits being squashed into a single commit? but I'd love to know where the specific code change came from.

The function I'm looking at is hasIngredient in src/main/java/appeng/menu/me/common/MEStorageMenu.java.

The function gets added to forge/master from the commit "1.20.1", last week: a571a9b?diff=split#diff-f11625a624859ec5d425e6a3dc687e69f6bc37950e025571816d9d9038c200ee

But it also gets added in the commit "1.19.4" on forge/1.19.4 in May: c0a9dd4?diff=split#diff-f11625a624859ec5d425e6a3dc687e69f6bc37950e025571816d9d9038c200ee

As I discovered yesterday, it's also added in the commit "1.19.3" (f8d3db4) from December 2022.

So, clearly this code change must exist somewhere that's not master, and it keeps getting added into the forge branches by whichever process is used to push changes onto the forge/* branches?

commented

The change (being added in a giant commit along with a bunch of other changes) goes back at least as far as Feb 2022: 0dc6894#diff-f11625a624859ec5d425e6a3dc687e69f6bc37950e025571816d9d9038c200ee

Edit: it goes back at least as far as the first forge tag, this is in the commit "Back to Forge 2021" from Jan 10 2022: a337535#diff-f11625a624859ec5d425e6a3dc687e69f6bc37950e025571816d9d9038c200ee

It's only in the forge tags/branches, not the fabric ones, it's almost as if whatever is being used to squish the forge commits is re-adding this function each time a new squished-commit is made? It's very strange.

commented

I can only reproduce this when I have "ME DISK Drive"s from AE2Things. I suspect it's not about the drives themselves but the fact that they have a lot of items in them?

I can reproduce this without AE2Things drives. My system has at most 4284 different items (68 storage cells), none with obscenely large NBT data. I can reproduce the issue (including the same hot functions) with recipes as trivial as those for stone or white wool.