mirror of
https://github.com/SparklyPower/SparklyPaper.git
synced 2025-12-19 15:09:27 +00:00
Honestly, some of these changes felt like hopium "surely this will fix the lag issues", even tho in my mind these didn't make sense Yeah, these methods do show up in the profiler, but does these *really* make sense? I don't think so, I think these are just useless patches that only attempt to hide the pain, instead of tackling the REAL issue that is causing these methods to show up in the profiler
140 lines
8.0 KiB
Diff
140 lines
8.0 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: MrPowerGamerBR <git@mrpowergamerbr.com>
|
|
Date: Thu, 23 Nov 2023 18:05:00 -0300
|
|
Subject: [PATCH] Cache last shouldTickBlocksAt result when ticking block
|
|
entities
|
|
|
|
The "shouldTickBlocksAt" call is expensive, it requires pulling chunk holder info from an map for each block entity (even if the block entities are on the same chunk!) every single time
|
|
|
|
So here's a quick and dirty optimization: We cache the last "shouldTickBlocksAt" result and, if the last chunk position is the same as our cached value, we use the last cached "shouldTickBlocksAt" result!
|
|
|
|
We could use a map for caching, but here's why this is way better than using a map: The block entity ticking list is sorted by chunks! Well, sort of... It is sorted by chunk when the chunk has been loaded, newly placed blocks will be appended to the end of the list until the chunk unloads and loads again
|
|
|
|
But here's the thing: We don't care if this is bad, the small performance hit of when a player placed new block entities is so small ('tis just a integer comparsion after all), that the huge performance boost from already placed block entities is way bigger
|
|
|
|
Most block entities are things that players placed to be there for a long time anyway (like hoppers, etc)
|
|
|
|
We also cache the chunk's coordinate key when creating the block entity, which is actually "free" because we just reuse the already cached chunk coordinate key from the chunk!
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
|
index b9e0822638a3979bd43392efdb595153e6f34675..b008bbc1bfef5d2ea53ed2fbffa505a398b9f26c 100644
|
|
--- a/src/main/java/net/minecraft/world/level/Level.java
|
|
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
|
@@ -1272,6 +1272,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
|
int tilesThisCycle = 0;
|
|
var toRemove = new it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet<TickingBlockEntity>(net.minecraft.Util.identityStrategy()); // Paper - use removeAll
|
|
toRemove.add(null);
|
|
+ // SparklyPaper start - cache last shouldTickBlocksAt result when ticking block entities
|
|
+ var shouldTickBlocksAtLastResult = -1; // -1 = undefined
|
|
+ var shouldTickBlocksAtChunkPos = 0L;
|
|
+ // SparklyPaper end
|
|
for (tileTickPosition = 0; tileTickPosition < this.blockEntityTickers.size(); tileTickPosition++) { // Paper - Disable tick limiters
|
|
this.tileTickPosition = (this.tileTickPosition < this.blockEntityTickers.size()) ? this.tileTickPosition : 0;
|
|
TickingBlockEntity tickingblockentity = (TickingBlockEntity) this.blockEntityTickers.get(this.tileTickPosition);
|
|
@@ -1288,13 +1292,25 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
|
tilesThisCycle--;
|
|
toRemove.add(tickingblockentity); // Paper - use removeAll
|
|
// Spigot end
|
|
- } else if (this.shouldTickBlocksAt(tickingblockentity.getPos())) {
|
|
+ // } else if (this.shouldTickBlocksAt(tickingblockentity.getPos())) { // SparklyPaper start - cache last shouldTickBlocksAt result when ticking block entities
|
|
+ } else {
|
|
+ long chunkPos = tickingblockentity.getChunkCoordinateKey();
|
|
+ boolean shouldTick;
|
|
+ if (shouldTickBlocksAtChunkPos == chunkPos && shouldTickBlocksAtLastResult != -1) {
|
|
+ shouldTick = shouldTickBlocksAtLastResult == 1;
|
|
+ } else {
|
|
+ shouldTick = this.shouldTickBlocksAt(chunkPos);
|
|
+ shouldTickBlocksAtLastResult = shouldTick ? 1 : 0;
|
|
+ shouldTickBlocksAtChunkPos = chunkPos;
|
|
+ }
|
|
+ if (shouldTick) {
|
|
tickingblockentity.tick();
|
|
// Paper start - execute chunk tasks during tick
|
|
if ((this.tileTickPosition & 7) == 0) {
|
|
MinecraftServer.getServer().executeMidTickTasks();
|
|
}
|
|
// Paper end - execute chunk tasks during tick
|
|
+ } // SparklyPaper end
|
|
}
|
|
}
|
|
this.blockEntityTickers.removeAll(toRemove);
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/TickingBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/TickingBlockEntity.java
|
|
index 28e3b73507b988f7234cbf29c4024c88180d0aef..68d96dd3e288346d8df49b52fa035e8154057065 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/TickingBlockEntity.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/TickingBlockEntity.java
|
|
@@ -10,4 +10,6 @@ public interface TickingBlockEntity {
|
|
BlockPos getPos();
|
|
|
|
String getType();
|
|
+
|
|
+ long getChunkCoordinateKey(); // SparklyPaper - cache last shouldTickBlocksAt result when ticking block entities
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
|
index fa170cc1ce7011d201295b89718292d696c7fc24..c6f62c56da6e74fbaa57300f8cc2718675d1681e 100644
|
|
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
|
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
|
@@ -73,6 +73,13 @@ public class LevelChunk extends ChunkAccess {
|
|
public String getType() {
|
|
return "<null>";
|
|
}
|
|
+
|
|
+ // SparklyPaper start - cache last shouldTickBlocksAt result when ticking block entities
|
|
+ @Override
|
|
+ public long getChunkCoordinateKey() {
|
|
+ return 0;
|
|
+ }
|
|
+ // SparklyPaper end
|
|
};
|
|
private final Map<BlockPos, LevelChunk.RebindableTickingBlockEntityWrapper> tickersInLevel;
|
|
public boolean loaded;
|
|
@@ -1090,7 +1097,7 @@ public class LevelChunk extends ChunkAccess {
|
|
}
|
|
|
|
private <T extends BlockEntity> TickingBlockEntity createTicker(T blockEntity, BlockEntityTicker<T> blockEntityTicker) {
|
|
- return new LevelChunk.BoundTickingBlockEntity<>(blockEntity, blockEntityTicker);
|
|
+ return new LevelChunk.BoundTickingBlockEntity<>(blockEntity, blockEntityTicker, coordinateKey); // SparklyPaper - cache last shouldTickBlocksAt result when ticking block entities
|
|
}
|
|
|
|
@FunctionalInterface
|
|
@@ -1141,6 +1148,13 @@ public class LevelChunk extends ChunkAccess {
|
|
public String toString() {
|
|
return this.ticker + " <wrapped>";
|
|
}
|
|
+
|
|
+ // SparklyPaper start - cache last shouldTickBlocksAt result when ticking block entities
|
|
+ @Override
|
|
+ public long getChunkCoordinateKey() {
|
|
+ return this.ticker.getChunkCoordinateKey();
|
|
+ }
|
|
+ // SparklyPaper end
|
|
}
|
|
|
|
private class BoundTickingBlockEntity<T extends BlockEntity> implements TickingBlockEntity {
|
|
@@ -1148,10 +1162,12 @@ public class LevelChunk extends ChunkAccess {
|
|
private final T blockEntity;
|
|
private final BlockEntityTicker<T> ticker;
|
|
private boolean loggedInvalidBlockState;
|
|
+ private final long chunkCoordinateKey; // SparklyPaper - cache last shouldTickBlocksAt result when ticking block entities
|
|
|
|
- BoundTickingBlockEntity(BlockEntity tileentity, BlockEntityTicker blockentityticker) {
|
|
+ BoundTickingBlockEntity(BlockEntity tileentity, BlockEntityTicker blockentityticker, long chunkCoordinateKey) { // SparklyPaper - cache last shouldTickBlocksAt result when ticking block entities
|
|
this.blockEntity = (T) tileentity; // CraftBukkit - decompile error
|
|
this.ticker = blockentityticker;
|
|
+ this.chunkCoordinateKey = chunkCoordinateKey; // SparklyPaper - cache last shouldTickBlocksAt result when ticking block entities
|
|
}
|
|
|
|
@Override
|
|
@@ -1214,5 +1230,12 @@ public class LevelChunk extends ChunkAccess {
|
|
|
|
return "Level ticker for " + s + "@" + this.getPos();
|
|
}
|
|
+
|
|
+ // SparklyPaper start - cache last shouldTickBlocksAt result when ticking block entities
|
|
+ @Override
|
|
+ public long getChunkCoordinateKey() {
|
|
+ return this.chunkCoordinateKey;
|
|
+ }
|
|
+ // SparklyPaper end
|
|
}
|
|
}
|