Profile categories splitting and descriptions. (#1375)
* Split spawning and random ticks into separate categories * Split blocks into tile ticks and block events * Fix ambiguous call to tick() method Fix package private warning * fix: add missing sections for tile ticks and block events * fix: wrong profiling order * feat: add descriptions to profiler categories * refactor: replace guava ImmutableMap with jdk Map * fix negative time in "rest" category
This commit is contained in:
1 parent
4662a86121
commit
544c1a8327
4 files changed
+134
-56
No files matched your search
@@ -15,16 +15,16 @@ import net.minecraft.server.level.ServerLevel;
|
|||||||
@Mixin(ChunkMap.class)
|
@Mixin(ChunkMap.class)
|
||||||
public class ChunkMap_tickMixin
|
public class ChunkMap_tickMixin
|
||||||
{
|
{
|
||||||
@Shadow @Final private ServerLevel level;
|
@Shadow @Final ServerLevel level;
|
||||||
CarpetProfiler.ProfilerToken currentSection;
|
CarpetProfiler.ProfilerToken currentSection;
|
||||||
|
|
||||||
@Inject(method = "tick", at = @At("HEAD"))
|
@Inject(method = "tick(Ljava/util/function/BooleanSupplier;)V", at = @At("HEAD"))
|
||||||
private void startProfilerSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
|
private void startProfilerSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
|
||||||
{
|
{
|
||||||
currentSection = CarpetProfiler.start_section(level, "Unloading", CarpetProfiler.TYPE.GENERAL);
|
currentSection = CarpetProfiler.start_section(level, "Unloading", CarpetProfiler.TYPE.GENERAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "tick", at = @At("RETURN"))
|
@Inject(method = "tick(Ljava/util/function/BooleanSupplier;)V", at = @At("RETURN"))
|
||||||
private void stopProfilerSecion(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
|
private void stopProfilerSecion(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
|
||||||
{
|
{
|
||||||
if (currentSection != null)
|
if (currentSection != null)
|
||||||
@@ -32,7 +32,4 @@ public class ChunkMap_tickMixin
|
|||||||
CarpetProfiler.end_current_section(currentSection);
|
CarpetProfiler.end_current_section(currentSection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -25,7 +25,7 @@ import com.google.common.collect.Lists;
|
|||||||
public abstract class ServerChunkCache_tickMixin
|
public abstract class ServerChunkCache_tickMixin
|
||||||
{
|
{
|
||||||
|
|
||||||
@Shadow @Final private ServerLevel level;
|
@Shadow @Final ServerLevel level;
|
||||||
|
|
||||||
@Shadow @Final
|
@Shadow @Final
|
||||||
public ChunkMap chunkMap;
|
public ChunkMap chunkMap;
|
||||||
@@ -35,7 +35,30 @@ public abstract class ServerChunkCache_tickMixin
|
|||||||
@Inject(method = "tickChunks", at = @At("HEAD"))
|
@Inject(method = "tickChunks", at = @At("HEAD"))
|
||||||
private void startSpawningSection(CallbackInfo ci)
|
private void startSpawningSection(CallbackInfo ci)
|
||||||
{
|
{
|
||||||
currentSection = CarpetProfiler.start_section(level, "Spawning and Random Ticks", CarpetProfiler.TYPE.GENERAL);
|
currentSection = CarpetProfiler.start_section(level, "Spawning", CarpetProfiler.TYPE.GENERAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "tickChunks", at = @At(
|
||||||
|
value = "FIELD",
|
||||||
|
target = "net/minecraft/server/level/ServerChunkCache.level:Lnet/minecraft/server/level/ServerLevel;",
|
||||||
|
ordinal = 10
|
||||||
|
))
|
||||||
|
private void skipChunkTicking(CallbackInfo ci)
|
||||||
|
{
|
||||||
|
if (currentSection != null)
|
||||||
|
{
|
||||||
|
CarpetProfiler.end_current_section(currentSection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "tickChunks", at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "net/minecraft/server/level/ServerLevel.tickChunk(Lnet/minecraft/world/level/chunk/LevelChunk;I)V",
|
||||||
|
shift = At.Shift.AFTER
|
||||||
|
))
|
||||||
|
private void resumeSpawningSection(CallbackInfo ci)
|
||||||
|
{
|
||||||
|
currentSection = CarpetProfiler.start_section(level, "Spawning", CarpetProfiler.TYPE.GENERAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "tickChunks", at = @At("RETURN"))
|
@Inject(method = "tickChunks", at = @At("RETURN"))
|
||||||
|
|||||||
@@ -47,69 +47,54 @@ public abstract class ServerLevel_tickMixin extends Level
|
|||||||
}
|
}
|
||||||
@Inject(method = "tick", at = @At(
|
@Inject(method = "tick", at = @At(
|
||||||
value = "CONSTANT",
|
value = "CONSTANT",
|
||||||
args = "stringValue=chunkSource"
|
args = "stringValue=tickPending"
|
||||||
))
|
))
|
||||||
private void stopWeatherStartChunkSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
|
private void stopWeatherStartTileTicks(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
|
||||||
{
|
{
|
||||||
if (currentSection != null)
|
if (currentSection != null)
|
||||||
{
|
{
|
||||||
CarpetProfiler.end_current_section(currentSection);
|
CarpetProfiler.end_current_section(currentSection);
|
||||||
// we go deeper here
|
currentSection = CarpetProfiler.start_section((Level) (Object) this, "Schedule Ticks", CarpetProfiler.TYPE.GENERAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Inject(method = "tick", at = @At(
|
|
||||||
value = "CONSTANT",
|
|
||||||
args = "stringValue=tickPending"
|
|
||||||
))
|
|
||||||
private void stopChunkStartBlockSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
|
|
||||||
{
|
|
||||||
if (currentSection != null)
|
|
||||||
{
|
|
||||||
// out of chunk
|
|
||||||
currentSection = CarpetProfiler.start_section((Level) (Object) this, "Blocks", CarpetProfiler.TYPE.GENERAL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "tick", at = @At(
|
@Inject(method = "tick", at = @At(
|
||||||
value = "CONSTANT",
|
value = "CONSTANT",
|
||||||
args = "stringValue=raid"
|
args = "stringValue=raid"
|
||||||
))
|
))
|
||||||
private void stopBlockStartVillageSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
|
private void stopTileTicksStartRaid(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
|
||||||
{
|
{
|
||||||
if (currentSection != null)
|
if (currentSection != null)
|
||||||
{
|
{
|
||||||
CarpetProfiler.end_current_section(currentSection);
|
CarpetProfiler.end_current_section(currentSection);
|
||||||
currentSection = CarpetProfiler.start_section((Level) (Object) this, "Village", CarpetProfiler.TYPE.GENERAL);
|
currentSection = CarpetProfiler.start_section((Level) (Object) this, "Raid", CarpetProfiler.TYPE.GENERAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "tick", at = @At(
|
@Inject(method = "tick", at = @At(
|
||||||
value = "CONSTANT",
|
value = "CONSTANT",
|
||||||
args = "stringValue=chunkSource"
|
args = "stringValue=chunkSource"
|
||||||
))
|
))
|
||||||
private void stopVillageSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
|
private void stopRaid(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
|
||||||
{
|
{
|
||||||
if (currentSection != null)
|
if (currentSection != null)
|
||||||
{
|
{
|
||||||
CarpetProfiler.end_current_section(currentSection);
|
CarpetProfiler.end_current_section(currentSection);
|
||||||
currentSection = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Inject(method = "tick", at = @At(
|
@Inject(method = "tick", at = @At(
|
||||||
value = "CONSTANT",
|
value = "CONSTANT",
|
||||||
args = "stringValue=blockEvents"
|
args = "stringValue=blockEvents"
|
||||||
))
|
))
|
||||||
private void startBlockAgainSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
|
private void startBlockEvents(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
|
||||||
{
|
{
|
||||||
currentSection = CarpetProfiler.start_section((Level) (Object) this, "Blocks", CarpetProfiler.TYPE.GENERAL);
|
currentSection = CarpetProfiler.start_section((Level) (Object) this, "Block Events", CarpetProfiler.TYPE.GENERAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "tick", at = @At(
|
@Inject(method = "tick", at = @At(
|
||||||
value = "CONSTANT",
|
value = "CONSTANT",
|
||||||
args = "stringValue=entities"
|
args = "stringValue=entities"
|
||||||
))
|
))
|
||||||
private void stopBlockAgainStartEntitySection(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
|
private void stopBlockEventsStartEntitySection(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
|
||||||
{
|
{
|
||||||
if (currentSection != null)
|
if (currentSection != null)
|
||||||
{
|
{
|
||||||
@@ -126,6 +111,45 @@ public abstract class ServerLevel_tickMixin extends Level
|
|||||||
private void endEntitySection(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
|
private void endEntitySection(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
|
||||||
{
|
{
|
||||||
CarpetProfiler.end_current_section(currentSection);
|
CarpetProfiler.end_current_section(currentSection);
|
||||||
|
currentSection = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chunk
|
||||||
|
|
||||||
|
@Inject(method = "tickChunk", at = @At("HEAD"))
|
||||||
|
private void startThunderSpawningSection(CallbackInfo ci) {
|
||||||
|
// Counting it in spawning because it's spawning skeleton horses
|
||||||
|
currentSection = CarpetProfiler.start_section((Level) (Object) this, "Spawning", CarpetProfiler.TYPE.GENERAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "tickChunk", at = @At(
|
||||||
|
value = "CONSTANT",
|
||||||
|
args = "stringValue=iceandsnow"
|
||||||
|
))
|
||||||
|
private void endThunderSpawningAndStartIceSnowRandomTicks(CallbackInfo ci) {
|
||||||
|
if (currentSection != null) {
|
||||||
|
CarpetProfiler.end_current_section(currentSection);
|
||||||
|
currentSection = CarpetProfiler.start_section((Level) (Object) this, "Environment", CarpetProfiler.TYPE.GENERAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "tickChunk", at = @At(
|
||||||
|
value = "CONSTANT",
|
||||||
|
args = "stringValue=tickBlocks"
|
||||||
|
))
|
||||||
|
private void endIceAndSnowAndStartRandomTicks(CallbackInfo ci) {
|
||||||
|
if (currentSection != null) {
|
||||||
|
CarpetProfiler.end_current_section(currentSection);
|
||||||
|
currentSection = CarpetProfiler.start_section((Level) (Object) this, "Random Ticks", CarpetProfiler.TYPE.GENERAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "tickChunk", at = @At("RETURN"))
|
||||||
|
private void endRandomTicks(CallbackInfo ci) {
|
||||||
|
if (currentSection != null) {
|
||||||
|
CarpetProfiler.end_current_section(currentSection);
|
||||||
|
currentSection = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//// freeze
|
//// freeze
|
||||||
@@ -181,6 +205,4 @@ public abstract class ServerLevel_tickMixin extends Level
|
|||||||
{
|
{
|
||||||
if (TickSpeed.process_entities) runBlockEvents();
|
if (TickSpeed.process_entities) runBlockEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -31,16 +31,38 @@ public class CarpetProfiler
|
|||||||
private static int tick_health_elapsed = 0;
|
private static int tick_health_elapsed = 0;
|
||||||
private static TYPE test_type = TYPE.NONE; //1 for ticks, 2 for entities
|
private static TYPE test_type = TYPE.NONE; //1 for ticks, 2 for entities
|
||||||
private static long current_tick_start = 0;
|
private static long current_tick_start = 0;
|
||||||
private static final String[] GENERAL_SECTIONS = {"Network", "Autosave", "Async Tasks", "Datapacks", "Carpet"};
|
private static final Map<String, String> GENERAL_SECTIONS = Map.of(
|
||||||
private static final String[] SCARPET_SECTIONS = {
|
"Network", "Packet sending, player logins, disconnects, kicks, anti-cheat check for player movement, etc.",
|
||||||
"Scarpet run", "Scarpet events", "Scarpet schedule",
|
"Autosave", "Autosave",
|
||||||
"Scarpet command", "Scarpet load", "Scarpet app data", "Scarpet client"
|
"Async Tasks", "Various asynchronous tasks on the server. Mainly chunk generation, chunk saving, etc.",
|
||||||
};
|
"Datapacks", "Datapack tick function execution. Load function execution if reload was performed.",
|
||||||
private static final String[] SECTIONS = {
|
"Carpet", "Player hud, scripts, and extensions (If they choose to use carpet's onTick)."
|
||||||
"Spawning and Random Ticks", "Ticket Manager","Unloading",
|
);
|
||||||
"Blocks", "Entities", "Block Entities",
|
|
||||||
"Entities (Client)", "Block Entities (Client)",
|
private static final Map<String, String> SCARPET_SECTIONS = Map.of(
|
||||||
"Village", "Environment"};
|
"Scarpet run", "script run command execution",
|
||||||
|
"Scarpet events", "script events, custom or built-in",
|
||||||
|
"Scarpet schedule", "script scheduled calls/events",
|
||||||
|
"Scarpet command", "script custom commands. Calls, executions, suggestions, etc.",
|
||||||
|
"Scarpet load", "script and libraries (if required) loading",
|
||||||
|
"Scarpet app data", "script module data (if required) ticking and saving",
|
||||||
|
"Scarpet client", "script shape rendering. (Client side)"
|
||||||
|
);
|
||||||
|
|
||||||
|
private static final Map<String, String> SECTIONS = Map.ofEntries(
|
||||||
|
Map.entry("Spawning", "Spawning of various things. Natural mobs, cats, patrols, wandering traders, phantoms, skeleton horses, etc."),
|
||||||
|
Map.entry("Random Ticks", "Random ticks. Both block random ticks and fluid random ticks."),
|
||||||
|
Map.entry("Ticket Manager", "Chunk ticket manager. Assigning tickets, removing tickets, etc."),
|
||||||
|
Map.entry("Unloading", "POI ticking and chunk unloading."),
|
||||||
|
Map.entry("Schedule Ticks", "Scheduled ticks. Repeaters, observers, redstone torch, water, lava, etc."),
|
||||||
|
Map.entry("Block Events", "Scheduled Block events. Pistons, comparators, noteblocks, block entity events (chests opening/closing), etc."),
|
||||||
|
Map.entry("Entities", "All the entities in the server. Ticking, removing, despawning, dragon fight (if active), etc."),
|
||||||
|
Map.entry("Block Entities", "All the block entities in the server. Removal, ticking, etc."),
|
||||||
|
Map.entry("Entities (Client)", "Entity lag client side. Mostly rendering."),
|
||||||
|
Map.entry("Block Entities (Client)", "Block entity lag client side. Mostly rendering."),
|
||||||
|
Map.entry("Raid", "Raid ticking, stopping, etc."),
|
||||||
|
Map.entry("Environment", "Weather, time, waking up players, water freezing, cauldron filling, snow layers, etc.")
|
||||||
|
);
|
||||||
|
|
||||||
public enum TYPE
|
public enum TYPE
|
||||||
{
|
{
|
||||||
@@ -66,17 +88,17 @@ public class CarpetProfiler
|
|||||||
ENTITY_TIMES.clear();
|
ENTITY_TIMES.clear();
|
||||||
test_type = TYPE.GENERAL;
|
test_type = TYPE.GENERAL;
|
||||||
SECTION_STATS.put("tick", 0L);
|
SECTION_STATS.put("tick", 0L);
|
||||||
for (String section : GENERAL_SECTIONS)
|
for (String section : GENERAL_SECTIONS.keySet())
|
||||||
{
|
{
|
||||||
SECTION_STATS.put(section, 0L);
|
SECTION_STATS.put(section, 0L);
|
||||||
}
|
}
|
||||||
for (String section : SCARPET_SECTIONS)
|
for (String section : SCARPET_SECTIONS.keySet())
|
||||||
{
|
{
|
||||||
SECTION_STATS.put(section, 0L);
|
SECTION_STATS.put(section, 0L);
|
||||||
}
|
}
|
||||||
for (ResourceKey<Level> level : source.getServer().levelKeys())
|
for (ResourceKey<Level> level : source.getServer().levelKeys())
|
||||||
{
|
{
|
||||||
for (String section : SECTIONS)
|
for (String section : SECTIONS.keySet())
|
||||||
{
|
{
|
||||||
SECTION_STATS.put(level.location() + "." + section, 0L);
|
SECTION_STATS.put(level.location() + "." + section, 0L);
|
||||||
}
|
}
|
||||||
@@ -198,21 +220,31 @@ public class CarpetProfiler
|
|||||||
Messenger.m(currentRequester, "wb Average tick time: ", String.format("yb %.3fms", divider * total_tick_time));
|
Messenger.m(currentRequester, "wb Average tick time: ", String.format("yb %.3fms", divider * total_tick_time));
|
||||||
long accumulated = 0L;
|
long accumulated = 0L;
|
||||||
|
|
||||||
for (String section : GENERAL_SECTIONS)
|
for (String section : GENERAL_SECTIONS.keySet())
|
||||||
{
|
{
|
||||||
double amount = divider * SECTION_STATS.get(section);
|
double amount = divider * SECTION_STATS.get(section);
|
||||||
if (amount > 0.01)
|
if (amount > 0.01)
|
||||||
{
|
{
|
||||||
accumulated += SECTION_STATS.get(section);
|
accumulated += SECTION_STATS.get(section);
|
||||||
Messenger.m(currentRequester, "w "+section+": ", String.format("y %.3fms", amount));
|
Messenger.m(
|
||||||
|
currentRequester,
|
||||||
|
"w " + section + ": ",
|
||||||
|
"^ " + GENERAL_SECTIONS.get(section),
|
||||||
|
"y %.3fms".formatted(amount)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (String section : SCARPET_SECTIONS)
|
for (String section : SCARPET_SECTIONS.keySet())
|
||||||
{
|
{
|
||||||
double amount = divider * SECTION_STATS.get(section);
|
double amount = divider * SECTION_STATS.get(section);
|
||||||
if (amount > 0.01)
|
if (amount > 0.01)
|
||||||
{
|
{
|
||||||
Messenger.m(currentRequester, "gi "+section+": ", String.format("di %.3fms", amount));
|
Messenger.m(
|
||||||
|
currentRequester,
|
||||||
|
"gi "+section+": ",
|
||||||
|
"^ " + SCARPET_SECTIONS.get(section),
|
||||||
|
"di %.3fms".formatted(amount)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,9 +252,8 @@ public class CarpetProfiler
|
|||||||
{
|
{
|
||||||
ResourceLocation dimensionId = dim.location();
|
ResourceLocation dimensionId = dim.location();
|
||||||
boolean hasSomethin = false;
|
boolean hasSomethin = false;
|
||||||
for (String section : SECTIONS)
|
for (String section : SECTIONS.keySet())
|
||||||
{
|
{
|
||||||
|
|
||||||
double amount = divider * SECTION_STATS.getOrDefault(dimensionId + "." + section, 0L);
|
double amount = divider * SECTION_STATS.getOrDefault(dimensionId + "." + section, 0L);
|
||||||
if (amount > 0.01)
|
if (amount > 0.01)
|
||||||
{
|
{
|
||||||
@@ -235,7 +266,7 @@ public class CarpetProfiler
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Messenger.m(currentRequester, "wb "+(dimensionId.getNamespace().equals("minecraft")?dimensionId.getPath():dimensionId.toString()) + ":");
|
Messenger.m(currentRequester, "wb "+(dimensionId.getNamespace().equals("minecraft")?dimensionId.getPath():dimensionId.toString()) + ":");
|
||||||
for (String section : SECTIONS)
|
for (String section : SECTIONS.keySet())
|
||||||
{
|
{
|
||||||
double amount = divider * SECTION_STATS.getOrDefault(dimensionId + "." + section, 0L);
|
double amount = divider * SECTION_STATS.getOrDefault(dimensionId + "." + section, 0L);
|
||||||
if (amount > 0.01)
|
if (amount > 0.01)
|
||||||
@@ -243,7 +274,12 @@ public class CarpetProfiler
|
|||||||
boolean cli = section.endsWith("(Client)");
|
boolean cli = section.endsWith("(Client)");
|
||||||
if (!cli)
|
if (!cli)
|
||||||
accumulated += SECTION_STATS.get(dimensionId + "." + section);
|
accumulated += SECTION_STATS.get(dimensionId + "." + section);
|
||||||
Messenger.m(currentRequester, String.format("%s - %s: ", cli?"gi":"w", section), String.format("%s %.3fms", cli?"di":"y", amount));
|
Messenger.m(
|
||||||
|
currentRequester,
|
||||||
|
"%s - %s: ".formatted(cli ? "gi" : "w", section),
|
||||||
|
"^ " + SECTIONS.get(section),
|
||||||
|
"%s %.3fms".formatted(cli ? "di" : "y", amount)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user