1
mirror of https://github.com/StarWishsama/Slimefun4.git synced 2024-09-19 19:25:48 +00:00

Added plugins summary to /sf timings

This commit is contained in:
TheBusyBiscuit 2020-07-03 14:47:51 +02:00
parent f03271a0d5
commit 06b14836dd
3 changed files with 64 additions and 22 deletions

View File

@ -3,6 +3,8 @@ package io.github.thebusybiscuit.slimefun4.core.networks.energy;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.LongConsumer;
import org.bukkit.Location;
import org.bukkit.Material;
@ -13,6 +15,7 @@ import io.github.thebusybiscuit.slimefun4.api.ErrorReport;
import io.github.thebusybiscuit.slimefun4.api.network.Network;
import io.github.thebusybiscuit.slimefun4.api.network.NetworkComponent;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.Reactor;
import io.github.thebusybiscuit.slimefun4.utils.holograms.SimpleHologram;
@ -127,6 +130,8 @@ public class EnergyNet extends Network {
}
public void tick(Block b) {
AtomicLong timestamp = new AtomicLong(SlimefunPlugin.getProfiler().newEntry());
if (!regulator.equals(b.getLocation())) {
SimpleHologram.update(b, "&4Multiple Energy Regulators connected");
return;
@ -138,7 +143,7 @@ public class EnergyNet extends Network {
SimpleHologram.update(b, "&4No Energy Network found");
}
else {
double supply = DoubleHandler.fixDouble(tickAllGenerators() + tickAllCapacitors());
double supply = DoubleHandler.fixDouble(tickAllGenerators(timestamp::getAndAdd) + tickAllCapacitors());
double demand = 0;
int availableEnergy = (int) supply;
@ -167,6 +172,9 @@ public class EnergyNet extends Network {
storeExcessEnergy(availableEnergy);
updateHologram(b, supply, demand);
}
// We have subtracted the timings from Generators, so they do not show up twice.
SlimefunPlugin.getProfiler().closeEntry(b.getLocation(), SlimefunItems.ENERGY_REGULATOR.getItem(), timestamp.get());
}
private void storeExcessEnergy(int available) {
@ -209,7 +217,7 @@ public class EnergyNet extends Network {
}
}
private double tickAllGenerators() {
private double tickAllGenerators(LongConsumer timeCallback) {
double supply = 0;
Set<Location> exploded = new HashSet<>();
@ -249,7 +257,8 @@ public class EnergyNet extends Network {
new ErrorReport(t, source, item);
}
SlimefunPlugin.getProfiler().closeEntry(source, item, timestamp);
long time = SlimefunPlugin.getProfiler().closeEntry(source, item, timestamp);
timeCallback.accept(time);
}
else {
// This block seems to be gone now, better remove it to be extra safe

View File

@ -21,7 +21,7 @@ import net.md_5.bungee.api.chat.TextComponent;
class PerformanceSummary {
// The threshold at which a Block or Chunk is significant enough to appear in /sf timings
private static final int VISIBILITY_THRESHOLD = 275_000;
private static final int VISIBILITY_THRESHOLD = 280_000;
// A minecraft server tick is 50ms and Slimefun ticks are stretched across
// two ticks (sync and async blocks), so we use 100ms as a reference here
@ -34,6 +34,7 @@ class PerformanceSummary {
private final float percentage;
private final Map<String, Long> chunks;
private final Map<String, Long> plugins;
private final Map<String, Long> items;
PerformanceSummary(SlimefunProfiler profiler, long totalElapsedTime, int totalTickedBlocks) {
@ -44,6 +45,7 @@ class PerformanceSummary {
this.totalTickedBlocks = totalTickedBlocks;
chunks = profiler.getByChunk();
plugins = profiler.getByPlugin();
items = profiler.getByItem();
}
@ -52,44 +54,47 @@ class PerformanceSummary {
sender.sendMessage(ChatColor.GREEN + "===== Slimefun Lag Profiler =====");
sender.sendMessage(ChatColor.GOLD + "Total: " + ChatColor.YELLOW + NumberUtils.getAsMillis(totalElapsedTime));
sender.sendMessage(ChatColor.GOLD + "Performance: " + getPerformanceRating());
sender.sendMessage(ChatColor.GOLD + "Active Chunks: " + ChatColor.YELLOW + chunks.size());
sender.sendMessage(ChatColor.GOLD + "Active Blocks: " + ChatColor.YELLOW + totalTickedBlocks);
sender.sendMessage("");
summarizeTimings("Blocks", sender, entry -> {
summarizeTimings(totalTickedBlocks + " Blocks", sender, items, entry -> {
int count = profiler.getBlocksOfId(entry.getKey());
String time = NumberUtils.getAsMillis(entry.getValue());
if (count > 1) {
String average = NumberUtils.getAsMillis(entry.getValue() / count);
return entry.getKey() + " - " + count + "x (" + time + ", " + average + " avg/block)";
return entry.getKey() + " - " + count + "x (" + time + " | avg: " + average + ')';
}
else {
return entry.getKey() + " - " + count + "x (" + time + ')';
}
}, items.entrySet().stream());
});
sender.sendMessage("");
summarizeTimings("Chunks", sender, entry -> {
summarizeTimings(chunks.size() + " Chunks", sender, chunks, entry -> {
int count = profiler.getBlocksInChunk(entry.getKey());
String time = NumberUtils.getAsMillis(entry.getValue());
return entry.getKey() + " - " + count + "x (" + time + ")";
}, chunks.entrySet().stream());
return entry.getKey() + " - " + count + "x Blocks (" + time + ")";
});
summarizeTimings(plugins.size() + " Plugins", sender, plugins, entry -> {
int count = profiler.getBlocksFromPlugin(entry.getKey());
String time = NumberUtils.getAsMillis(entry.getValue());
return entry.getKey() + " - " + count + "x Blocks (" + time + ")";
});
}
private void summarizeTimings(String prefix, CommandSender sender, Function<Map.Entry<String, Long>, String> formatter, Stream<Map.Entry<String, Long>> stream) {
private void summarizeTimings(String prefix, CommandSender sender, Map<String, Long> map, Function<Map.Entry<String, Long>, String> formatter) {
Stream<Map.Entry<String, Long>> stream = map.entrySet().stream();
List<Entry<String, Long>> results = stream.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toList());
if (sender instanceof Player) {
TextComponent component = new TextComponent(prefix);
component.setColor(ChatColor.GOLD);
component.setColor(ChatColor.YELLOW);
TextComponent hoverComponent = new TextComponent("\n Hover for more details...");
TextComponent hoverComponent = new TextComponent(" (Hover for details)");
hoverComponent.setColor(ChatColor.GRAY);
hoverComponent.setItalic(true);
StringBuilder builder = new StringBuilder();
int hidden = 0;
@ -111,11 +116,13 @@ class PerformanceSummary {
else {
int hidden = 0;
StringBuilder builder = new StringBuilder();
builder.append(ChatColor.GOLD + prefix);
builder.append(ChatColor.GOLD);
builder.append(prefix);
builder.append(ChatColor.YELLOW);
for (Map.Entry<String, Long> entry : results) {
if (entry.getValue() > VISIBILITY_THRESHOLD) {
builder.append(" ");
builder.append("\n ");
builder.append(ChatColor.stripColor(formatter.apply(entry)));
}
else {

View File

@ -83,10 +83,12 @@ public class SlimefunProfiler {
* The {@link SlimefunItem} at this {@link Location}
* @param timestamp
* The timestamp marking the start of this entry, you can retrieve it using {@link #newEntry()}
*
* @return The total timings of this entry
*/
public void closeEntry(Location l, SlimefunItem item, long timestamp) {
public long closeEntry(Location l, SlimefunItem item, long timestamp) {
if (timestamp == 0) {
return;
return 0;
}
long elapsedTime = System.nanoTime() - timestamp;
@ -96,6 +98,8 @@ public class SlimefunProfiler {
timings.put(block, elapsedTime);
queued.decrementAndGet();
});
return elapsedTime;
}
/**
@ -166,6 +170,16 @@ public class SlimefunProfiler {
return map;
}
protected Map<String, Long> getByPlugin() {
Map<String, Long> map = new HashMap<>();
for (Map.Entry<ProfiledBlock, Long> entry : timings.entrySet()) {
map.merge(entry.getKey().getAddon().getName(), entry.getValue(), Long::sum);
}
return map;
}
protected Map<String, Long> getByChunk() {
Map<String, Long> map = new HashMap<>();
@ -208,6 +222,18 @@ public class SlimefunProfiler {
return blocks;
}
protected int getBlocksFromPlugin(String id) {
int blocks = 0;
for (ProfiledBlock block : timings.keySet()) {
if (block.getAddon().getName().equals(id)) {
blocks++;
}
}
return blocks;
}
protected float getPercentageOfTick() {
float millis = totalElapsedTime / 1000000.0F;
float fraction = (millis * 100.0F) / PerformanceSummary.MAX_TICK_DURATION;