Skip to content

Commit

Permalink
Simplify canHoldFluid condition logic
Browse files Browse the repository at this point in the history
Cache the result of half of canHoldFluid logic, since there is a state#is in this method,
it uses map contains to do iteration to check whether a block has a specific block tag key,
which the contains iteration call is very expensive if called everytime
Also, I simplified the condition logic in the original method to be more readable.
It is actually useless since the result is cached, just makes it look better.

In the test, it can improve ~30% performance in ~1577000 times of canHoldFluid calls (~159ms -> ~111ms)
  • Loading branch information
Dreeam-qwq committed Nov 29, 2024
1 parent ec419e7 commit 4dc313c
Showing 1 changed file with 95 additions and 0 deletions.
95 changes: 95 additions & 0 deletions patches/server/0162-Simplify-canHoldFluid-condition-logic.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dreeam <[email protected]>
Date: Tue, 26 Nov 2024 17:15:38 -0500
Subject: [PATCH] Simplify canHoldFluid condition logic

Cache the result of half of canHoldFluid logic, since there is a state#is in this method,
it uses map contains to do iteration to check whether a block has a specific block tag key,
which the contains iteration call is very expensive if called everytime
Also, I simplified the condition logic in the original method to be more readable.
It is actually useless since the result is cached, just makes it look better.

In the test, it can improve ~30% performance in ~1577000 times of canHoldFluid calls (~159ms -> ~111ms)

diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
index de299465937074a1067a6adfc208eaaa24bcae67..235ba8f5edc9e75d2b8e34ecd65df791aa7e4ff2 100644
--- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
+++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
@@ -794,6 +794,7 @@ public abstract class BlockBehaviour implements FeatureElement {
protected BlockBehaviour.BlockStateBase.Cache cache;
private FluidState fluidState;
private boolean isRandomlyTicking;
+ private boolean canHoldFluidInternal; // Leaf - Simplify canHoldFluid condition logic

// Paper start - rewrite chunk system
private int opacityIfCached;
@@ -929,6 +930,7 @@ public abstract class BlockBehaviour implements FeatureElement {
this.shapeExceedsCube = this.cache == null || this.cache.largeCollisionShape; // Paper - moved from actual method to here

this.legacySolid = this.calculateSolid();
+ this.canHoldFluidInternal = org.dreeam.leaf.util.fluid.FluidUtil.canHoldFluidInternal(this.getBlock(), this.asState()); // Leaf - Simplify canHoldFluid condition logic
// Paper start - rewrite chunk system
this.isConditionallyFullOpaque = this.canOcclude & this.useShapeForLightOcclusion;
this.opacityIfCached = this.cache == null || this.isConditionallyFullOpaque ? -1 : this.cache.lightBlock;
@@ -990,6 +992,12 @@ public abstract class BlockBehaviour implements FeatureElement {
return this.legacySolid;
}

+ // Leaf start - Simplify canHoldFluid condition logic
+ public boolean canHoldFluidInternal() {
+ return canHoldFluidInternal;
+ }
+ // Leaf end - Simplify canHoldFluid condition logic
+
// Paper start - Protect Bedrock and End Portal/Frames from being destroyed
public final boolean isDestroyable() {
return getBlock().isDestroyable();
diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
index bf9c228a19fe34221686f1d002feda7f40e8272c..e3b23cb01aa25afcef32ce87bb4aafa6e418f190 100644
--- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
+++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
@@ -520,7 +520,7 @@ public abstract class FlowingFluid extends Fluid {
if (block instanceof LiquidBlockContainer ifluidcontainer) {
return ifluidcontainer.canPlaceLiquid((Player) null, world, pos, state, fluid);
} else {
- return !(block instanceof DoorBlock) && !state.is(BlockTags.SIGNS) && !state.is(Blocks.LADDER) && !state.is(Blocks.SUGAR_CANE) && !state.is(Blocks.BUBBLE_COLUMN) ? (!state.is(Blocks.NETHER_PORTAL) && !state.is(Blocks.END_PORTAL) && !state.is(Blocks.END_GATEWAY) && !state.is(Blocks.STRUCTURE_VOID) ? !state.blocksMotion() : false) : false;
+ return state.canHoldFluidInternal(); // Leaf - Simplify canHoldFluid condition logic
}
}

diff --git a/src/main/java/org/dreeam/leaf/util/fluid/FluidUtil.java b/src/main/java/org/dreeam/leaf/util/fluid/FluidUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..de6744e5f11c394f4d64aab2bb94a81aa12432f2
--- /dev/null
+++ b/src/main/java/org/dreeam/leaf/util/fluid/FluidUtil.java
@@ -0,0 +1,30 @@
+package org.dreeam.leaf.util.fluid;
+
+import net.minecraft.tags.BlockTags;
+import net.minecraft.world.level.block.Block;
+import net.minecraft.world.level.block.Blocks;
+import net.minecraft.world.level.block.DoorBlock;
+import net.minecraft.world.level.block.state.BlockState;
+
+public class FluidUtil {
+
+ public static boolean canHoldFluidInternal(Block block, BlockState state) {
+ if (block instanceof DoorBlock ||
+ state.is(BlockTags.SIGNS) ||
+ block == Blocks.LADDER ||
+ block == Blocks.SUGAR_CANE ||
+ block == Blocks.BUBBLE_COLUMN) {
+ return false;
+ }
+
+ if (block == Blocks.NETHER_PORTAL ||
+ block == Blocks.END_PORTAL ||
+ block == Blocks.END_GATEWAY ||
+ block == Blocks.STRUCTURE_VOID) {
+ return false;
+ }
+
+ // Same with !state.blocksMotion()
+ return block == Blocks.COBWEB || block == Blocks.BAMBOO_SAPLING || !state.isSolid();
+ }
+}

0 comments on commit 4dc313c

Please sign in to comment.