Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Many hasRecipe calls, no cache #123

Closed
cha0s opened this issue Aug 31, 2022 · 6 comments
Closed

Many hasRecipe calls, no cache #123

cha0s opened this issue Aug 31, 2022 · 6 comments
Labels
bug Something isn't working

Comments

@cha0s
Copy link

cha0s commented Aug 31, 2022

Forge Version

40.1.74

Fabric Version

No response

Iron Furnaces Version

1.18.2-3.3.1

Describe your issue

Performance is absolutely terrible.

Look at that percent, sheesh

As you can see, it's all about the recipe lookups:

oooof

I tried installing https://www.curseforge.com/minecraft/mc-mods/fastfurnace hoping that its recipe caching would apply to this mod. It doesn't.

This is critical for multiplayer servers. The profile I'm showing is one user's one single furnace on a 2-day-old server. That's absurd.

Crash Report

No response

@cha0s cha0s added the bug Something isn't working label Aug 31, 2022
@cha0s
Copy link
Author

cha0s commented Aug 31, 2022

My initial thought would be an LRU cache for recipes, set to maybe n * 2 where n is the number of slots in the current factory.

@cha0s
Copy link
Author

cha0s commented Sep 1, 2022

Just wanted to note that I am having a chance to sit down and look at the code and I already see LRU recipe caches! So there may be more to the problem than I first thought. I am learning more!

@cha0s
Copy link
Author

cha0s commented Sep 1, 2022

Alright, I worked my way through and found a config option:

[furnaces]
	recipe_cache = 30

to use in ironfurnaces-server.toml. The default is 10. I am going to tune this a bit and experiment.

I'm curious whether you think it might be worth tuning defaults? Or even, implementing a dynamic LRU cache by measuring the amount of recipe requests per n where n could equal 1 tick or 1 second or whatever makes sense after tuning.

@cha0s cha0s changed the title Terrible performance Excessive recipe cache misses due to per-slot factory cache Sep 1, 2022
@cha0s
Copy link
Author

cha0s commented Sep 1, 2022

Okay, still digging (do you have a Discord? :))

It seems like tick doesn't even use the recipe cache. getCache is only called once: from getSpeed.

@cha0s
Copy link
Author

cha0s commented Sep 1, 2022

I think this is the real fix:

diff --git a/src/main/java/ironfurnaces/tileentity/furnaces/BlockIronFurnaceTileBase.java b/src/main/java/ironfurnaces/tileentity/furnaces/BlockIronFurnaceTileBase.java
index a16b4ee..2a908ea 100644
--- a/src/main/java/ironfurnaces/tileentity/furnaces/BlockIronFurnaceTileBase.java
+++ b/src/main/java/ironfurnaces/tileentity/furnaces/BlockIronFurnaceTileBase.java
@@ -892,7 +892,7 @@ public abstract class BlockIronFurnaceTileBase extends TileEntityInventory imple
                 if (e.isBurning() || !itemstack.isEmpty() && !e.getItem(INPUT).isEmpty()) {
                     Optional<AbstractCookingRecipe> irecipe = Optional.empty();
                     if (!e.getItem(INPUT).isEmpty()) {
-                        irecipe = e.getRecipe(e.getItem(INPUT));
+                        irecipe = e.getCache().computeIfAbsent(e.getItem(INPUT).getItem(), (item) -> e.getRecipe(new ItemStack(item)));
                     }
 
                     boolean valid = e.canSmelt(irecipe.orElse(null));

Unfortunately gradlew is hanging when I try to build. Next problem,

@cha0s
Copy link
Author

cha0s commented Sep 1, 2022

I was able to work through the problems and I was able to stress test. Before the change the furnace tick time was 28ms. With this change the tick time is ~0.2ms once the cache size is tuned.

#124

@cha0s cha0s closed this as completed Sep 1, 2022
@cha0s cha0s changed the title Excessive recipe cache misses due to per-slot factory cache Many hasRecipe calls, no cache Sep 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant