mirror of
https://github.com/SparklyPower/SparklyPaper.git
synced 2026-01-04 15:41:34 +00:00
Let's start from scratch, shall we?
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrPowerGamerBR <git@mrpowergamerbr.com>
|
||||
Date: Sun, 22 Oct 2023 12:27:26 -0300
|
||||
Subject: [PATCH] Only check thundering once per world instead for every chunk
|
||||
|
||||
For some reason the isThundering check is consuming ~3% of CPU time when profiled so, instead of checking the thunder every chunk, we can cache the result and reuse on the same chunk tick
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
index c02ffd419236980cd063741612e99d739d97ec94..daa5948cc7b86a719a313ea595f135cd00b6a3cc 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -599,6 +599,7 @@ public class ServerChunkCache extends ChunkSource {
|
||||
}
|
||||
// Paper end - optimise chunk tick iteration
|
||||
|
||||
+ this.level.isCurrentlyThundering = this.level.isThundering_old(); // SparklyPaper - Only check thundering once per world instead for every chunk
|
||||
int chunksTicked = 0; // Paper
|
||||
// Paper start - optimise chunk tick iteration
|
||||
io.papermc.paper.util.player.NearbyPlayers nearbyPlayers = this.chunkMap.getNearbyPlayers(); // Paper - optimise chunk tick iteration
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index 9388dd9b34bb8148ce8b5f7e24122fa4bd1bafa8..0210226d2185803a18c0020d7985c1fccb798953 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -184,6 +184,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
private int tileTickPosition;
|
||||
public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions
|
||||
public java.util.ArrayDeque<net.minecraft.world.level.block.RedstoneTorchBlock.Toggle> redstoneUpdateInfos; // Paper - Move from Map in BlockRedstoneTorch to here
|
||||
+ public boolean isCurrentlyThundering; // SparklyPaper - Only check if the world is currently thundering once instead for every chunk
|
||||
|
||||
// Paper start - fix and optimise world upgrading
|
||||
// copied from below
|
||||
@@ -1614,7 +1615,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
this.rainLevel = f1;
|
||||
}
|
||||
|
||||
+ // SparklyPaper start - Only check thundering once per world instead for every chunk
|
||||
public boolean isThundering() {
|
||||
+ return isCurrentlyThundering;
|
||||
+ }
|
||||
+ public boolean isThundering_old() {
|
||||
+ // SparklyPaper end
|
||||
return this.dimensionType().hasSkyLight() && !this.dimensionType().hasCeiling() ? (double) this.getThunderLevel(1.0F) > 0.9D : false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrPowerGamerBR <git@mrpowergamerbr.com>
|
||||
Date: Sat, 28 Oct 2023 19:02:12 -0300
|
||||
Subject: [PATCH] Optimize heavy EntityLookup.ArrayIterable.<init>() calls on
|
||||
tickChunks
|
||||
|
||||
For some reason, on SparklyPower allocating an ArrayIterable is expensive, taking around ~2.5% of tick time (I have no idea why tho), because tickChunks() only uses this for the NaturalSpawner, let's avoid the array allocation by passing thru the raw array data + size
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/chunk/system/entity/EntityLookup.java b/src/main/java/io/papermc/paper/chunk/system/entity/EntityLookup.java
|
||||
index 15ee41452992714108efe53b708b5a4e1da7c1ff..f5a5796dda9e0e05ed9afc069c241dedd9aaffa0 100644
|
||||
--- a/src/main/java/io/papermc/paper/chunk/system/entity/EntityLookup.java
|
||||
+++ b/src/main/java/io/papermc/paper/chunk/system/entity/EntityLookup.java
|
||||
@@ -198,6 +198,12 @@ public final class EntityLookup implements LevelEntityGetter<Entity> {
|
||||
return Arrays.copyOf(this.accessibleEntities.getRawData(), this.accessibleEntities.size(), Entity[].class);
|
||||
}
|
||||
|
||||
+ // SparklyPaper start - Optimize heavy EntityLookup$ArrayIterable.<init>() calls on tickChunks
|
||||
+ public EntityList getAccessibleEntities() {
|
||||
+ return this.accessibleEntities;
|
||||
+ }
|
||||
+ // SparklyPaper end
|
||||
+
|
||||
@Override
|
||||
public <U extends Entity> void get(final EntityTypeTest<Entity, U> filter, final AbortableIterationConsumer<U> action) {
|
||||
final Int2ReferenceOpenHashMap<Entity> entityCopy;
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
index f8270b78ab0d561e55301e989d80fe7b4118337a..e51d06140153e7f9a6e41b20addf02ec94e0f72c 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -545,9 +545,9 @@ public class ServerChunkCache extends ChunkSource {
|
||||
}
|
||||
// Paper end - per player mob spawning backoff
|
||||
}
|
||||
- spawnercreature_d = NaturalSpawner.createState(l, this.level.getAllEntities(), this::getFullChunk, null, true);
|
||||
+ spawnercreature_d = NaturalSpawner.createState(l, this.level.getEntityLookup().getAccessibleEntities().getRawData(), this.level.getEntityLookup().getAccessibleEntities().size(), this::getFullChunk, null, true); // SparklyPaper - Optimize heavy EntityLookup$ArrayIterable.<init>() calls on tickChunks
|
||||
} else {
|
||||
- spawnercreature_d = NaturalSpawner.createState(l, this.level.getAllEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false);
|
||||
+ spawnercreature_d = NaturalSpawner.createState(l, this.level.getEntityLookup().getAccessibleEntities().getRawData(), this.level.getEntityLookup().getAccessibleEntities().size(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false); // SparklyPaper - Optimize heavy EntityLookup$ArrayIterable.<init>() calls on tickChunks
|
||||
}
|
||||
// Paper end
|
||||
this.level.timings.countNaturalMobs.stopTiming(); // Paper - timings
|
||||
diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
||||
index 9c2d62feff1816f5729060c6192269a5b2d34153..78bcb0af0735fe0ccf68ed06d8dc78d6e8c37064 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
||||
@@ -74,7 +74,60 @@ public final class NaturalSpawner {
|
||||
return createState(spawningChunkCount, entities, chunkSource, densityCapper, false);
|
||||
}
|
||||
|
||||
+ // SparklyPaper start - Optimize heavy EntityLookup$ArrayIterable.<init>() calls on tickChunks
|
||||
+ public static NaturalSpawner.SpawnState createState(int spawningChunkCount, Entity[] entities, int count, NaturalSpawner.ChunkGetter chunkSource, LocalMobCapCalculator densityCapper, boolean countMobs) {
|
||||
+ PotentialCalculator spawnercreatureprobabilities = new PotentialCalculator();
|
||||
+ Object2IntOpenHashMap<MobCategory> object2intopenhashmap = new Object2IntOpenHashMap();
|
||||
+
|
||||
+ for (int index = 0; count > index; index++) {
|
||||
+ Entity entity = entities[index];
|
||||
+
|
||||
+ if (entity instanceof Mob) {
|
||||
+ Mob entityinsentient = (Mob) entity;
|
||||
+
|
||||
+ if (entityinsentient.isPersistenceRequired() || entityinsentient.requiresCustomPersistence()) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ MobCategory enumcreaturetype = entity.getType().getCategory();
|
||||
+
|
||||
+ if (enumcreaturetype != MobCategory.MISC) {
|
||||
+ // Paper start - Only count natural spawns
|
||||
+ if (!entity.level().paperConfig().entities.spawning.countAllMobsForSpawning &&
|
||||
+ !(entity.spawnReason == org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL ||
|
||||
+ entity.spawnReason == org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.CHUNK_GEN)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+ BlockPos blockposition = entity.blockPosition();
|
||||
+
|
||||
+ chunkSource.query(ChunkPos.asLong(blockposition), (chunk) -> {
|
||||
+ MobSpawnSettings.MobSpawnCost biomesettingsmobs_b = NaturalSpawner.getRoughBiome(blockposition, chunk).getMobSettings().getMobSpawnCost(entity.getType());
|
||||
+
|
||||
+ if (biomesettingsmobs_b != null) {
|
||||
+ spawnercreatureprobabilities.addCharge(entity.blockPosition(), biomesettingsmobs_b.charge());
|
||||
+ }
|
||||
+
|
||||
+ if (densityCapper != null && entity instanceof Mob) { // Paper
|
||||
+ densityCapper.addMob(chunk.getPos(), enumcreaturetype);
|
||||
+ }
|
||||
+
|
||||
+ object2intopenhashmap.addTo(enumcreaturetype, 1);
|
||||
+ // Paper start
|
||||
+ if (countMobs) {
|
||||
+ chunk.level.getChunkSource().chunkMap.updatePlayerMobTypeMap(entity);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+ });
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return new NaturalSpawner.SpawnState(spawningChunkCount, object2intopenhashmap, spawnercreatureprobabilities, densityCapper);
|
||||
+ }
|
||||
+
|
||||
public static NaturalSpawner.SpawnState createState(int spawningChunkCount, Iterable<Entity> entities, NaturalSpawner.ChunkGetter chunkSource, LocalMobCapCalculator densityCapper, boolean countMobs) {
|
||||
+ // SparklyPaper end
|
||||
// Paper end
|
||||
PotentialCalculator spawnercreatureprobabilities = new PotentialCalculator();
|
||||
Object2IntOpenHashMap<MobCategory> object2intopenhashmap = new Object2IntOpenHashMap();
|
||||
Reference in New Issue
Block a user