Add JMH benchmarks, improve storage performance of StorageService#getAvailableStacks >50% - #8904
Conversation
|
My gut feeling on this topic has been: we should not build an index on secondary key values (damage) at all unless there's actually an observer that requires that information (meaning an export bus or level that uses a fuzzy upgrade) |
|
I am also sorry, we're not going to merge this in 1.20.1 |
|
Thanks @shartte for looking at this.
This sounds pretty reasonable to me, and the flame graphs show a lot of time spent in the AVL tree code. Do you want me to explore this in this initial optimization pass, in a follow-up pr, or explore it yourself?
Would you like me to retarget this PR at |
|
I looked into porting this change to main, and I'm running into a problem: I want to use Items in the JMH tests, but the only way to get Items seems to be to have minecraft bootstrapped. It looks like the infrastructure is already built to bootstrap minecraft for JUnit tests, but I can't find something similar for JMH. I see broadly two ways forward:
I'll keep investigating these to try and get these tests runnable on main. The only other NeoForge mod i'm aware of that uses JMH appears to do so without depending on bootstrapping in any of its tests: https://github.com/neoforged/Bus/tree/main/bus-jmh/src/main/java/net/neoforged/bus/benchmarks . So that would be a point in favor of the second strategy. |
TL;DR: This patch includes performance improvements of 50-200% for AE2 server tick times.
On our recent Monifactory playthrough, we noticed our endgame ME network was a substantial performance hog on server resources, bringing us down to ~9 TPS. Most of the time was spent in onServerEndTick, processing the contents of the networks in the StorageService.
I wrote some microbenchmarks to target these codepaths using the existing API, made changes to the implementation to optimize those benchmarks, wrote a script to summarize those improvements as a graph, and manually validated the change by applying it to our server to achieve 13-20 TPS.
Here's the graph summarizing the performance gains:

To run individual benchmarks (takes ~5 minutes) and experiment with the changes directly and see flamegraphs, use
./gradlew jmhTo run the full suite (takes ~1.5 hours) use
node scripts/run_jmh_tests.mjs.To generate the graph as an svg, use
node scripts/generate_report.mjs.All of the results are in
build/results/jmh/.Some lingering concerns I have:
mainand while there are some conflicts, overall this performance problem is still present.