Merge a few put(get()+n) into fastutil's addTo to remove hash operations
This commit is contained in:
1 parent
65fe8a19bb
commit
df240159ff
1 file changed
+41
-51
@@ -15,15 +15,15 @@ import net.minecraft.world.level.block.entity.BlockEntityType;
|
|||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
import static java.util.Map.entry;
|
||||||
|
|
||||||
public class CarpetProfiler
|
public class CarpetProfiler
|
||||||
{
|
{
|
||||||
private static final Map<String, Long> SECTION_STATS = new HashMap<>();
|
private static final Object2LongOpenHashMap<String> SECTION_STATS = new Object2LongOpenHashMap<>();
|
||||||
private static final Object2LongMap<Pair<Level,Object>> ENTITY_TIMES = new Object2LongOpenHashMap<>();
|
private static final Object2LongOpenHashMap<Pair<Level,Object>> ENTITY_TIMES = new Object2LongOpenHashMap<>();
|
||||||
private static final Object2LongMap<Pair<Level,Object>> ENTITY_COUNT = new Object2LongOpenHashMap<>();
|
private static final Object2LongOpenHashMap<Pair<Level,Object>> ENTITY_COUNT = new Object2LongOpenHashMap<>();
|
||||||
|
|
||||||
|
|
||||||
private static CommandSourceStack currentRequester = null;
|
private static CommandSourceStack currentRequester = null;
|
||||||
@@ -50,18 +50,18 @@ public class CarpetProfiler
|
|||||||
);
|
);
|
||||||
|
|
||||||
private static final Map<String, String> SECTIONS = Map.ofEntries(
|
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."),
|
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."),
|
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."),
|
entry("Ticket Manager", "Chunk ticket manager. Assigning tickets, removing tickets, etc."),
|
||||||
Map.entry("Unloading", "POI ticking and chunk unloading."),
|
entry("Unloading", "POI ticking and chunk unloading."),
|
||||||
Map.entry("Schedule Ticks", "Scheduled ticks. Repeaters, observers, redstone torch, water, lava, etc."),
|
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."),
|
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."),
|
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."),
|
entry("Block Entities", "All the block entities in the server. Removal, ticking, etc."),
|
||||||
Map.entry("Entities (Client)", "Entity lag client side. Mostly rendering."),
|
entry("Entities (Client)", "Entity lag client side. Mostly rendering."),
|
||||||
Map.entry("Block Entities (Client)", "Block entity lag client side. Mostly rendering."),
|
entry("Block Entities (Client)", "Block entity lag client side. Mostly rendering."),
|
||||||
Map.entry("Raid", "Raid ticking, stopping, etc."),
|
entry("Raid", "Raid ticking, stopping, etc."),
|
||||||
Map.entry("Environment", "Weather, time, waking up players, water freezing, cauldron filling, snow layers, etc.")
|
entry("Environment", "Weather, time, waking up players, water freezing, cauldron filling, snow layers, etc.")
|
||||||
);
|
);
|
||||||
|
|
||||||
public enum TYPE
|
public enum TYPE
|
||||||
@@ -83,26 +83,10 @@ public class CarpetProfiler
|
|||||||
public static void prepare_tick_report(CommandSourceStack source, int ticks)
|
public static void prepare_tick_report(CommandSourceStack source, int ticks)
|
||||||
{
|
{
|
||||||
//maybe add so it only spams the sending player, but honestly - all may want to see it
|
//maybe add so it only spams the sending player, but honestly - all may want to see it
|
||||||
SECTION_STATS.clear();
|
SECTION_STATS.clear(); // everything then defaults to 0
|
||||||
ENTITY_COUNT.clear();
|
ENTITY_COUNT.clear();
|
||||||
ENTITY_TIMES.clear();
|
ENTITY_TIMES.clear();
|
||||||
test_type = TYPE.GENERAL;
|
test_type = TYPE.GENERAL;
|
||||||
SECTION_STATS.put("tick", 0L);
|
|
||||||
for (String section : GENERAL_SECTIONS.keySet())
|
|
||||||
{
|
|
||||||
SECTION_STATS.put(section, 0L);
|
|
||||||
}
|
|
||||||
for (String section : SCARPET_SECTIONS.keySet())
|
|
||||||
{
|
|
||||||
SECTION_STATS.put(section, 0L);
|
|
||||||
}
|
|
||||||
for (ResourceKey<Level> level : source.getServer().levelKeys())
|
|
||||||
{
|
|
||||||
for (String section : SECTIONS.keySet())
|
|
||||||
{
|
|
||||||
SECTION_STATS.put(level.location() + "." + section, 0L);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tick_health_elapsed = ticks;
|
tick_health_elapsed = ticks;
|
||||||
tick_health_requested = ticks;
|
tick_health_requested = ticks;
|
||||||
@@ -114,7 +98,6 @@ public class CarpetProfiler
|
|||||||
{
|
{
|
||||||
//maybe add so it only spams the sending player, but honestly - all may want to see it
|
//maybe add so it only spams the sending player, but honestly - all may want to see it
|
||||||
SECTION_STATS.clear();
|
SECTION_STATS.clear();
|
||||||
SECTION_STATS.put("tick", 0L);
|
|
||||||
ENTITY_COUNT.clear();
|
ENTITY_COUNT.clear();
|
||||||
ENTITY_TIMES.clear();
|
ENTITY_TIMES.clear();
|
||||||
test_type = TYPE.ENTITY;
|
test_type = TYPE.ENTITY;
|
||||||
@@ -156,7 +139,7 @@ public class CarpetProfiler
|
|||||||
String current_section = (world == null) ?
|
String current_section = (world == null) ?
|
||||||
(String) tok.section :
|
(String) tok.section :
|
||||||
String.format("%s.%s%s", world.dimension().location(), tok.section, world.isClientSide ? " (Client)" : "");
|
String.format("%s.%s%s", world.dimension().location(), tok.section, world.isClientSide ? " (Client)" : "");
|
||||||
SECTION_STATS.put(current_section, SECTION_STATS.getOrDefault(current_section, 0L) + end_time - tok.start);
|
SECTION_STATS.addTo(current_section, end_time - tok.start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,8 +149,8 @@ public class CarpetProfiler
|
|||||||
return;
|
return;
|
||||||
long end_time = System.nanoTime();
|
long end_time = System.nanoTime();
|
||||||
Pair<Level,Object> section = Pair.of(tok.world, tok.section);
|
Pair<Level,Object> section = Pair.of(tok.world, tok.section);
|
||||||
ENTITY_TIMES.put(section, ENTITY_TIMES.getOrDefault(section, 0L) + end_time - tok.start);
|
ENTITY_TIMES.addTo(section, end_time - tok.start);
|
||||||
ENTITY_COUNT.put(section, ENTITY_COUNT.getOrDefault(section, 0L) + 1);
|
ENTITY_COUNT.addTo(section, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void start_tick_profiling()
|
public static void start_tick_profiling()
|
||||||
@@ -179,7 +162,7 @@ public class CarpetProfiler
|
|||||||
{
|
{
|
||||||
if (current_tick_start == 0L)
|
if (current_tick_start == 0L)
|
||||||
return;
|
return;
|
||||||
SECTION_STATS.put("tick", SECTION_STATS.get("tick") + System.nanoTime() - current_tick_start);
|
SECTION_STATS.addTo("tick", System.nanoTime() - current_tick_start);
|
||||||
tick_health_elapsed--;
|
tick_health_elapsed--;
|
||||||
if (tick_health_elapsed <= 0)
|
if (tick_health_elapsed <= 0)
|
||||||
{
|
{
|
||||||
@@ -199,7 +182,6 @@ public class CarpetProfiler
|
|||||||
public static void cleanup_tick_report()
|
public static void cleanup_tick_report()
|
||||||
{
|
{
|
||||||
SECTION_STATS.clear();
|
SECTION_STATS.clear();
|
||||||
SECTION_STATS.put("tick", 0L);
|
|
||||||
ENTITY_TIMES.clear();
|
ENTITY_TIMES.clear();
|
||||||
ENTITY_COUNT.clear();
|
ENTITY_COUNT.clear();
|
||||||
test_type = TYPE.NONE;
|
test_type = TYPE.NONE;
|
||||||
@@ -214,7 +196,7 @@ public class CarpetProfiler
|
|||||||
//print stats
|
//print stats
|
||||||
if (currentRequester == null)
|
if (currentRequester == null)
|
||||||
return;
|
return;
|
||||||
long total_tick_time = SECTION_STATS.get("tick");
|
long total_tick_time = SECTION_STATS.getLong("tick");
|
||||||
double divider = 1.0D / tick_health_requested / 1000000;
|
double divider = 1.0D / tick_health_requested / 1000000;
|
||||||
Messenger.m(currentRequester, "w ");
|
Messenger.m(currentRequester, "w ");
|
||||||
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));
|
||||||
@@ -222,10 +204,10 @@ public class CarpetProfiler
|
|||||||
|
|
||||||
for (String section : GENERAL_SECTIONS.keySet())
|
for (String section : GENERAL_SECTIONS.keySet())
|
||||||
{
|
{
|
||||||
double amount = divider * SECTION_STATS.get(section);
|
double amount = divider * SECTION_STATS.getLong(section);
|
||||||
if (amount > 0.01)
|
if (amount > 0.01)
|
||||||
{
|
{
|
||||||
accumulated += SECTION_STATS.get(section);
|
accumulated += SECTION_STATS.getLong(section);
|
||||||
Messenger.m(
|
Messenger.m(
|
||||||
currentRequester,
|
currentRequester,
|
||||||
"w " + section + ": ",
|
"w " + section + ": ",
|
||||||
@@ -236,7 +218,7 @@ public class CarpetProfiler
|
|||||||
}
|
}
|
||||||
for (String section : SCARPET_SECTIONS.keySet())
|
for (String section : SCARPET_SECTIONS.keySet())
|
||||||
{
|
{
|
||||||
double amount = divider * SECTION_STATS.get(section);
|
double amount = divider * SECTION_STATS.getLong(section);
|
||||||
if (amount > 0.01)
|
if (amount > 0.01)
|
||||||
{
|
{
|
||||||
Messenger.m(
|
Messenger.m(
|
||||||
@@ -254,7 +236,7 @@ public class CarpetProfiler
|
|||||||
boolean hasSomethin = false;
|
boolean hasSomethin = false;
|
||||||
for (String section : SECTIONS.keySet())
|
for (String section : SECTIONS.keySet())
|
||||||
{
|
{
|
||||||
double amount = divider * SECTION_STATS.getOrDefault(dimensionId + "." + section, 0L);
|
double amount = divider * SECTION_STATS.getLong(dimensionId + "." + section);
|
||||||
if (amount > 0.01)
|
if (amount > 0.01)
|
||||||
{
|
{
|
||||||
hasSomethin = true;
|
hasSomethin = true;
|
||||||
@@ -268,12 +250,12 @@ public class CarpetProfiler
|
|||||||
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.keySet())
|
for (String section : SECTIONS.keySet())
|
||||||
{
|
{
|
||||||
double amount = divider * SECTION_STATS.getOrDefault(dimensionId + "." + section, 0L);
|
double amount = divider * SECTION_STATS.getLong(dimensionId + "." + section);
|
||||||
if (amount > 0.01)
|
if (amount > 0.01)
|
||||||
{
|
{
|
||||||
boolean cli = section.endsWith("(Client)");
|
boolean cli = section.endsWith("(Client)");
|
||||||
if (!cli)
|
if (!cli)
|
||||||
accumulated += SECTION_STATS.get(dimensionId + "." + section);
|
accumulated += SECTION_STATS.getLong(dimensionId + "." + section);
|
||||||
Messenger.m(
|
Messenger.m(
|
||||||
currentRequester,
|
currentRequester,
|
||||||
"%s - %s: ".formatted(cli ? "gi" : "w", section),
|
"%s - %s: ".formatted(cli ? "gi" : "w", section),
|
||||||
@@ -314,15 +296,15 @@ public class CarpetProfiler
|
|||||||
{
|
{
|
||||||
if (currentRequester == null)
|
if (currentRequester == null)
|
||||||
return;
|
return;
|
||||||
long total_tick_time = SECTION_STATS.get("tick");
|
long total_tick_time = SECTION_STATS.getLong("tick");
|
||||||
double divider = 1.0D / tick_health_requested / 1000000;
|
double divider = 1.0D / tick_health_requested / 1000000;
|
||||||
double divider_1 = 1.0D / (tick_health_requested - 1) / 1000000;
|
double divider_1 = 1.0D / (tick_health_requested - 1) / 1000000;
|
||||||
Messenger.m(currentRequester, "w ");
|
Messenger.m(currentRequester, "w ");
|
||||||
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));
|
||||||
SECTION_STATS.remove("tick");
|
SECTION_STATS.removeLong("tick");
|
||||||
Messenger.m(currentRequester, "wb Top 10 counts:");
|
Messenger.m(currentRequester, "wb Top 10 counts:");
|
||||||
int total = 0;
|
int total = 0;
|
||||||
for (Object2LongMap.Entry<Pair<Level, Object>> sectionEntry : ENTITY_COUNT.object2LongEntrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toList()))
|
for (Object2LongMap.Entry<Pair<Level, Object>> sectionEntry : sortedByValue(ENTITY_COUNT))
|
||||||
{
|
{
|
||||||
if (++total > 10) break;
|
if (++total > 10) break;
|
||||||
Pair<Level,Object> section = sectionEntry.getKey();
|
Pair<Level,Object> section = sectionEntry.getKey();
|
||||||
@@ -336,7 +318,7 @@ public class CarpetProfiler
|
|||||||
}
|
}
|
||||||
Messenger.m(currentRequester, "wb Top 10 CPU hogs:");
|
Messenger.m(currentRequester, "wb Top 10 CPU hogs:");
|
||||||
total = 0;
|
total = 0;
|
||||||
for (Object2LongMap.Entry<Pair<Level,Object>> sectionEntry : ENTITY_TIMES.object2LongEntrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toList()))
|
for (Object2LongMap.Entry<Pair<Level, Object>> sectionEntry : sortedByValue(ENTITY_TIMES))
|
||||||
{
|
{
|
||||||
if (++total > 10) break;
|
if (++total > 10) break;
|
||||||
Pair<Level,Object> section = sectionEntry.getKey();
|
Pair<Level,Object> section = sectionEntry.getKey();
|
||||||
@@ -349,4 +331,12 @@ public class CarpetProfiler
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static <T> Iterable<Object2LongMap.Entry<T>> sortedByValue(Object2LongMap<T> mapToSort) {
|
||||||
|
return () -> mapToSort
|
||||||
|
.object2LongEntrySet()
|
||||||
|
.stream()
|
||||||
|
.sorted(Comparator.<Object2LongMap.Entry<T>>comparingLong(Object2LongMap.Entry::getLongValue).reversed())
|
||||||
|
.iterator();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user