Was profiling my server and noticed a decent chunk of thread time going through the fluid update path, mostly PluginBlockDynamicLiquid$Hooks.updateLiquidTick() -> FluidFlowHandler.updateDynamic() -> the getOptimalFlowDirectionsI/calculateFlowCostI recursion in IFluidUpdateHelper, plus the neighbor checks in ISpecializedFluidNeighborInfo/IFluidNeighborInfo underneath it.
From what I can tell, vanilla water flow is inherently expensive too, so I don't think this is necessarily a bug, Spark just seems to attribute the cost to Fluidlogged API specifically since the fluidlogging layer wraps the neighbor checks vanilla would otherwise do directly.
One thing that stood out poking through the code (not saying this is definitely worth changing, just flagging it in case it's useful): canFluidFlowI/canFluidConnectI in IFluidNeighborInfo allocate a new BlockPos every call, and there's a comment there noting it's a workaround ("this is dumb, but without it corner rendering breaks for some reason"). Since those two methods are called a lot during the flow-cost recursion, it looked like a possible allocation hotspot. Also noticed isFluidloggableI/isReplaceableI have a caching layer that's commented out, figured you probably disabled it for a reason (staleness bug or something), so not suggesting you just flip it back on blind.
Not trying to tell you how to fix it, you know this codebase way better than I do and probably have context I don't. Just wanted to pass along the profile in case it's useful if you ever want to take a look. Thanks for the mod either way, it's great.
(Spark profile attached )
https://spark.lucko.me/jN6TBTNi2Z
Was profiling my server and noticed a decent chunk of thread time going through the fluid update path, mostly PluginBlockDynamicLiquid$Hooks.updateLiquidTick() -> FluidFlowHandler.updateDynamic() -> the getOptimalFlowDirectionsI/calculateFlowCostI recursion in IFluidUpdateHelper, plus the neighbor checks in ISpecializedFluidNeighborInfo/IFluidNeighborInfo underneath it.
From what I can tell, vanilla water flow is inherently expensive too, so I don't think this is necessarily a bug, Spark just seems to attribute the cost to Fluidlogged API specifically since the fluidlogging layer wraps the neighbor checks vanilla would otherwise do directly.
One thing that stood out poking through the code (not saying this is definitely worth changing, just flagging it in case it's useful): canFluidFlowI/canFluidConnectI in IFluidNeighborInfo allocate a new BlockPos every call, and there's a comment there noting it's a workaround ("this is dumb, but without it corner rendering breaks for some reason"). Since those two methods are called a lot during the flow-cost recursion, it looked like a possible allocation hotspot. Also noticed isFluidloggableI/isReplaceableI have a caching layer that's commented out, figured you probably disabled it for a reason (staleness bug or something), so not suggesting you just flip it back on blind.
Not trying to tell you how to fix it, you know this codebase way better than I do and probably have context I don't. Just wanted to pass along the profile in case it's useful if you ever want to take a look. Thanks for the mod either way, it's great.
(Spark profile attached )
https://spark.lucko.me/jN6TBTNi2Z