From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Tue, 24 Jun 2025 07:05:51 -0700 Subject: [PATCH] Optimise EntityScheduler ticking The vast majority of the time, there are no tasks scheduled to the EntityScheduler. We can avoid iterating the entire entity list by tracking which schedulers have any tasks scheduled. diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java index 5f2deeb5cc01d8bbeb7449bd4e59c466b3dfdf57..82824ae7ffbced513a8bcace684af94916135e84 100644 --- a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java +++ b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java @@ -96,6 +96,7 @@ public final class ServerEntityLookup extends EntityLookup { if (entity instanceof ThrownEnderpearl enderpearl) { this.addEnderPearl(CoordinateUtils.getChunkKey(enderpearl.chunkPosition())); } + entity.registerScheduler(); // Paper - optimise Folia entity scheduler } @Override diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java index 382d2b6b53bd144f4d56dccdc603ed0da8fe07a7..7aac2a6889af3edaebfaf94deecbf00d00758b68 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java @@ -1654,33 +1654,22 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop serverPlayer1.connection.suspendFlushing()); this.server.getScheduler().mainThreadHeartbeat(); // CraftBukkit - // Paper start - Folia scheduler API - ((io.papermc.paper.threadedregions.scheduler.FoliaGlobalRegionScheduler) org.bukkit.Bukkit.getGlobalRegionScheduler()).tick(); - for (ServerPlayer player : this.playerList.players) { - if (!this.playerList.players.contains(player)) { + // Paper start - optimise Folia entity scheduler + ((io.papermc.paper.threadedregions.scheduler.FoliaGlobalRegionScheduler)org.bukkit.Bukkit.getGlobalRegionScheduler()).tick(); + for (io.papermc.paper.threadedregions.EntityScheduler scheduler : this.entitySchedulerTickList.getAllSchedulers()) { + if (scheduler.isRetired()) { continue; } - final org.bukkit.craftbukkit.entity.CraftEntity bukkit = player.getBukkitEntityRaw(); - if (bukkit != null) { - bukkit.taskScheduler.executeTick(); - } + + scheduler.executeTick(); } - getAllLevels().forEach(level -> { - for (final net.minecraft.world.entity.Entity entity : io.papermc.paper.FeatureHooks.getAllEntities(level)) { - if (entity.isRemoved() || entity instanceof ServerPlayer) { - continue; - } - final org.bukkit.craftbukkit.entity.CraftEntity bukkit = entity.getBukkitEntityRaw(); - if (bukkit != null) { - bukkit.taskScheduler.executeTick(); - } - } - }); - // Paper end - Folia scheduler API + // Paper end - optimise Folia entity scheduler io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.ADVENTURE_CLICK_MANAGER.handleQueue(this.tickCount); // Paper io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.DIALOG_CLICK_MANAGER.handleQueue(this.tickCount); // Paper profilerFiller.push("commandFunctions"); diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java index 813064b4d135c34cf76437a0f26546a8863abf85..70b6ea8ab35e88989b5b1f5ffd64490a9d743b56 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -5164,6 +5164,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.getBukkitEntity().taskScheduler.retire(); } // Paper end - Folia schedulers + // Paper start - optimise Folia entity scheduler + public final void registerScheduler() { + this.getBukkitEntity().taskScheduler.registerTo(net.minecraft.server.MinecraftServer.getServer().entitySchedulerTickList); + } + // Paper end - optimise Folia entity scheduler @Override public void setLevelCallback(EntityInLevelCallback levelCallback) {