neoforged / Bus

Event firing and listening framework, based on the event bus concept
GNU Lesser General Public License v2.1
3 stars 8 forks source link

Remove class transformations #2

Closed Technici4n closed 11 months ago

Technici4n commented 1 year ago

This PR contains a few well-separated commits, so here is an explanation for each of them:

Improve no-ASM event performance

Benchmark results

Note that this should not affect the ASM-based numbers, so only the ratio between ClassLoader/ModLauncher and NoLoader should be compared, not the absolute numbers.

Before

"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testClassLoaderCombined","avgt",1,15,195.116885,22.890661,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testClassLoaderDynamic","avgt",1,15,45.287124,1.658037,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testClassLoaderLambda","avgt",1,15,45.212152,1.900465,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testClassLoaderStatic","avgt",1,15,41.423441,1.497500,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testModLauncherCombined","avgt",1,15,190.569268,13.193654,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testModLauncherDynamic","avgt",1,15,50.533415,7.812138,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testModLauncherLambda","avgt",1,15,49.499213,5.892049,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testModLauncherStatic","avgt",1,15,45.407774,4.238560,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmarkNoLoader.testNoLoaderCombined","avgt",1,15,478.214420,53.847793,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmarkNoLoader.testNoLoaderDynamic","avgt",1,15,253.622357,18.208511,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmarkNoLoader.testNoLoaderLambda","avgt",1,15,250.663636,22.388767,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmarkNoLoader.testNoLoaderStatic","avgt",1,15,256.779737,23.325007,"ns/op"

After

"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testClassLoaderCombined","avgt",1,15,195.600813,63.858585,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testClassLoaderDynamic","avgt",1,15,64.506132,11.059437,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testClassLoaderLambda","avgt",1,15,58.684060,13.761499,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testClassLoaderStatic","avgt",1,15,52.215867,7.842289,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testModLauncherCombined","avgt",1,15,201.394879,38.587688,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testModLauncherDynamic","avgt",1,15,53.047444,7.618519,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testModLauncherLambda","avgt",1,15,60.348928,12.931862,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testModLauncherStatic","avgt",1,15,53.278237,7.752600,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmarkNoLoader.testNoLoaderCombined","avgt",1,15,242.090423,57.726100,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmarkNoLoader.testNoLoaderDynamic","avgt",1,15,64.889931,8.801521,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmarkNoLoader.testNoLoaderLambda","avgt",1,15,76.610469,18.534254,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmarkNoLoader.testNoLoaderStatic","avgt",1,15,53.906662,3.110215,"ns/op"

Use LambdaMetaFactory to invoke reflected event handlers

This approach is considerably simpler, and has similar performance to the ASM-based approaches. Sadly we need the IMPL_LOOKUP... :smile:

Benchmark

"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testClassLoaderCombined","avgt",1,15,154.030762,32.392691,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testClassLoaderDynamic","avgt",1,15,34.722512,1.650322,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testClassLoaderLambda","avgt",1,15,35.370152,1.432257,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testClassLoaderStatic","avgt",1,15,34.188926,2.815769,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testLMFCombined","avgt",1,15,132.833712,8.911560,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testLMFDynamic","avgt",1,15,34.490844,0.911256,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testLMFLambda","avgt",1,15,35.051102,1.981817,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testLMFStatic","avgt",1,15,32.638885,1.267960,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testModLauncherCombined","avgt",1,15,138.716408,9.358081,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testModLauncherDynamic","avgt",1,15,35.094794,2.084566,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testModLauncherLambda","avgt",1,15,36.005160,1.243836,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testModLauncherStatic","avgt",1,15,32.201514,1.629124,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmarkNoLoader.testNoLoaderCombined","avgt",1,15,143.372535,10.558159,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmarkNoLoader.testNoLoaderDynamic","avgt",1,15,44.412960,3.065631,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmarkNoLoader.testNoLoaderLambda","avgt",1,15,49.397381,7.591512,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmarkNoLoader.testNoLoaderStatic","avgt",1,15,52.220448,10.242142,"ns/op"

Based on these results, I removed the ClassLoader and ModLauncher factories.

Store listener list in a hashmap in the EventBus

Basically, we need an identityhashmap lookup, but we have one less indirection due to not having to get the listener list for the bus id. So the performance seems equivalent, and I thus removed all the ASM stuff.

Benchmark of the new approach (IdentityHashMap)

"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testModLauncherCombined","avgt",1,15,147.220979,8.021616,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testModLauncherDynamic","avgt",1,15,43.595994,1.966111,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testModLauncherLambda","avgt",1,15,44.917381,2.302097,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmark.testModLauncherStatic","avgt",1,15,43.071646,2.399672,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmarkNoLoader.testNoLoaderCombined","avgt",1,15,148.353504,6.817660,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmarkNoLoader.testNoLoaderDynamic","avgt",1,15,42.223318,2.750598,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmarkNoLoader.testNoLoaderLambda","avgt",1,15,44.432734,3.578886,"ns/op"
"net.minecraftforge.eventbus.benchmarks.EventBusBenchmarkNoLoader.testNoLoaderStatic","avgt",1,15,40.660543,2.406196,"ns/op"
Technici4n commented 11 months ago

Superseded by #24.