Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Profile categories splitting and descriptions. #1375

Merged
merged 10 commits into from
May 1, 2022
9 changes: 3 additions & 6 deletions src/main/java/carpet/mixins/ChunkMap_tickMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,21 @@
@Mixin(ChunkMap.class)
public class ChunkMap_tickMixin
{
@Shadow @Final private ServerLevel level;
@Shadow @Final ServerLevel level;
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)
{
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)
{
if (currentSection != null)
{
CarpetProfiler.end_current_section(currentSection);
}
}



}
27 changes: 25 additions & 2 deletions src/main/java/carpet/mixins/ServerChunkCache_tickMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
public abstract class ServerChunkCache_tickMixin
{

@Shadow @Final private ServerLevel level;
@Shadow @Final ServerLevel level;

@Shadow @Final
public ChunkMap chunkMap;
Expand All @@ -35,7 +35,30 @@ public abstract class ServerChunkCache_tickMixin
@Inject(method = "tickChunks", at = @At("HEAD"))
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"))
Expand Down
76 changes: 50 additions & 26 deletions src/main/java/carpet/mixins/ServerLevel_tickMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,69 +45,59 @@ private void startWeatherSection(BooleanSupplier booleanSupplier_1, CallbackInfo
}
@Inject(method = "tick", at = @At(
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)
{
CarpetProfiler.end_current_section(currentSection);
// we go deeper here
currentSection = CarpetProfiler.start_section((Level) (Object) this, "Tile Ticks", CarpetProfiler.TYPE.GENERAL);
}
}
@Inject(method = "tick", at = @At(
value = "CONSTANT",
args = "stringValue=tickPending"
args = "stringValue=raid"
))
private void stopChunkStartBlockSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
private void stopTileTicksStartRaid(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
{
if (currentSection != null)
{
// out of chunk
currentSection = CarpetProfiler.start_section((Level) (Object) this, "Blocks", CarpetProfiler.TYPE.GENERAL);
CarpetProfiler.end_current_section(currentSection);
currentSection = CarpetProfiler.start_section((Level) (Object) this, "Raid", CarpetProfiler.TYPE.GENERAL);
}
}

@Inject(method = "tick", at = @At(
value = "CONSTANT",
args = "stringValue=raid"
args = "stringValue=chunkSource"
))
private void stopBlockStartVillageSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
private void stopRaidStartChunkSource(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
{
if (currentSection != null)
{
CarpetProfiler.end_current_section(currentSection);
currentSection = CarpetProfiler.start_section((Level) (Object) this, "Village", CarpetProfiler.TYPE.GENERAL);
currentSection = CarpetProfiler.start_section((Level) (Object) this, "Unloading", CarpetProfiler.TYPE.GENERAL);
}
}
@Inject(method = "tick", at = @At(
value = "CONSTANT",
args = "stringValue=chunkSource"
args = "stringValue=blockEvents"
))
private void stopVillageSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
private void stopChunkSourceStartBlockEvents(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
{
if (currentSection != null)
{
CarpetProfiler.end_current_section(currentSection);
currentSection = null;
currentSection = CarpetProfiler.start_section((Level) (Object) this, "Block Events", CarpetProfiler.TYPE.GENERAL);
}
}


@Inject(method = "tick", at = @At(
value = "CONSTANT",
args = "stringValue=blockEvents"
))
private void startBlockAgainSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
{
currentSection = CarpetProfiler.start_section((Level) (Object) this, "Blocks", CarpetProfiler.TYPE.GENERAL);
}

@Inject(method = "tick", at = @At(
value = "CONSTANT",
args = "stringValue=entities"
))
private void stopBlockAgainStartEntitySection(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
private void stopBlockEventsStartEntitySection(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
{
if (currentSection != null)
{
Expand All @@ -126,6 +116,42 @@ private void endEntitySection(BooleanSupplier booleanSupplier_1, CallbackInfo ci
CarpetProfiler.end_current_section(currentSection);
}


@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 endIceSnowRandomTicks(CallbackInfo ci) {
if (currentSection != null) {
CarpetProfiler.end_current_section(currentSection);
}
}

//// freeze

@Redirect(method = "tick", at = @At(
Expand Down Expand Up @@ -179,6 +205,4 @@ private void tickConditionally(ServerLevel serverWorld)
{
if (TickSpeed.process_entities) runBlockEvents();
}


}
82 changes: 60 additions & 22 deletions src/main/java/carpet/utils/CarpetProfiler.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package carpet.utils;

import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableMap;
import it.unimi.dsi.fastutil.objects.Object2LongMap;
import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap;
import net.minecraft.commands.CommandSourceStack;
Expand Down Expand Up @@ -31,16 +33,38 @@ public class CarpetProfiler
private static int tick_health_elapsed = 0;
private static TYPE test_type = TYPE.NONE; //1 for ticks, 2 for entities
private static long current_tick_start = 0;
private static final String[] GENERAL_SECTIONS = {"Network", "Autosave", "Async Tasks", "Datapacks", "Carpet"};
private static final String[] SCARPET_SECTIONS = {
"Scarpet run", "Scarpet events", "Scarpet schedule",
"Scarpet command", "Scarpet load", "Scarpet app data", "Scarpet client"
};
private static final String[] SECTIONS = {
"Spawning and Random Ticks", "Ticket Manager","Unloading",
"Blocks", "Entities", "Block Entities",
"Entities (Client)", "Block Entities (Client)",
"Village", "Environment"};
private static final ImmutableMap<String, String> GENERAL_SECTIONS = ImmutableMap.of(
altrisi marked this conversation as resolved.
Show resolved Hide resolved
"Network", "Packet sending, player logins, disconnects, kicks, anti-cheat check for player movement, etc.",
"Autosave", "Autosave",
"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.",
"Carpet", "Player hud, scripts, and extensions (If they choose to use carpet's onTick)."
);

private static final ImmutableMap<String, String> SCARPET_SECTIONS = ImmutableMap.of(
"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 ImmutableMap<String, String> SECTIONS = new ImmutableMap.Builder<String, String>()
.put("Spawning", "Spawning of various things. Natural mobs, cat, patrol, wandering trader, phantom, skeleton horses, etc.")
.put("Random Ticks", "Random ticks. Both block and fluid random ticks.")
.put("Ticket Manager", "Chunk ticket manager. Assigning tickets, removing tickets, etc.")
.put("Unloading", "POI ticking and chunk unloading.")
.put("Tile Ticks", "Scheduled tile ticks. Repeaters, observers, redstone torch, water, lava, etc.")
.put("Block Events", "Scheduled Block events. Pistons, comparators, noteblocks, block entity events (chests opening/closing), etc.")
.put("Entities", "All the entities in the server. Ticking, removing, despawning, dragon fight (if active), etc.")
.put("Block Entities", "All the block entities in the server. Removal, ticking, etc.")
.put("Entities (Client)", "Entity lag client side. Mostly rendering.")
.put("Block Entities (Client)", "Block entity lag client side. Mostly rendering.")
.put("Raid", "Raid ticking, stopping, etc.")
.put("Environment", "Weather, time, waking up players, water freezing, cauldron filling, snow layers, etc.")
.build();

public enum TYPE
{
Expand All @@ -66,17 +90,17 @@ public static void prepare_tick_report(CommandSourceStack source, int ticks)
ENTITY_TIMES.clear();
test_type = TYPE.GENERAL;
SECTION_STATS.put("tick", 0L);
for (String section : GENERAL_SECTIONS)
for (String section : GENERAL_SECTIONS.keySet())
{
SECTION_STATS.put(section, 0L);
}
for (String section : SCARPET_SECTIONS)
for (String section : SCARPET_SECTIONS.keySet())
{
SECTION_STATS.put(section, 0L);
}
for (ResourceKey<Level> level : source.getServer().levelKeys())
{
for (String section : SECTIONS)
for (String section : SECTIONS.keySet())
{
SECTION_STATS.put(level.location() + "." + section, 0L);
}
Expand Down Expand Up @@ -198,31 +222,40 @@ public static void finalize_tick_report_for_time(MinecraftServer server)
Messenger.m(currentRequester, "wb Average tick time: ", String.format("yb %.3fms", divider * total_tick_time));
long accumulated = 0L;

for (String section : GENERAL_SECTIONS)
for (String section : GENERAL_SECTIONS.keySet())
{
double amount = divider * SECTION_STATS.get(section);
if (amount > 0.01)
{
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);
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)
);
}
}

for (ResourceKey<Level> dim : server.levelKeys())
{
ResourceLocation dimensionId = dim.location();
boolean hasSomethin = false;
for (String section : SECTIONS)
for (String section : SECTIONS.keySet())
{

double amount = divider * SECTION_STATS.getOrDefault(dimensionId + "." + section, 0L);
if (amount > 0.01)
{
Expand All @@ -235,15 +268,20 @@ public static void finalize_tick_report_for_time(MinecraftServer server)
continue;
}
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);
if (amount > 0.01)
{
boolean cli = section.endsWith("(Client)");
if (!cli)
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)
);
}
}
}
Expand Down Expand Up @@ -313,4 +351,4 @@ public static void finalize_tick_report_for_entities(MinecraftServer server)
));
}
}
}
}