mirror of
https://github.com/StarWishsama/Slimefun4.git
synced 2024-09-20 03:35:51 +00:00
Added plugins summary to /sf timings
This commit is contained in:
parent
f03271a0d5
commit
06b14836dd
@ -3,6 +3,8 @@ package io.github.thebusybiscuit.slimefun4.core.networks.energy;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.function.LongConsumer;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
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.Network;
|
||||||
import io.github.thebusybiscuit.slimefun4.api.network.NetworkComponent;
|
import io.github.thebusybiscuit.slimefun4.api.network.NetworkComponent;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
|
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.SlimefunPlugin;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.Reactor;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.Reactor;
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.holograms.SimpleHologram;
|
import io.github.thebusybiscuit.slimefun4.utils.holograms.SimpleHologram;
|
||||||
@ -127,6 +130,8 @@ public class EnergyNet extends Network {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void tick(Block b) {
|
public void tick(Block b) {
|
||||||
|
AtomicLong timestamp = new AtomicLong(SlimefunPlugin.getProfiler().newEntry());
|
||||||
|
|
||||||
if (!regulator.equals(b.getLocation())) {
|
if (!regulator.equals(b.getLocation())) {
|
||||||
SimpleHologram.update(b, "&4Multiple Energy Regulators connected");
|
SimpleHologram.update(b, "&4Multiple Energy Regulators connected");
|
||||||
return;
|
return;
|
||||||
@ -138,7 +143,7 @@ public class EnergyNet extends Network {
|
|||||||
SimpleHologram.update(b, "&4No Energy Network found");
|
SimpleHologram.update(b, "&4No Energy Network found");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
double supply = DoubleHandler.fixDouble(tickAllGenerators() + tickAllCapacitors());
|
double supply = DoubleHandler.fixDouble(tickAllGenerators(timestamp::getAndAdd) + tickAllCapacitors());
|
||||||
double demand = 0;
|
double demand = 0;
|
||||||
|
|
||||||
int availableEnergy = (int) supply;
|
int availableEnergy = (int) supply;
|
||||||
@ -167,6 +172,9 @@ public class EnergyNet extends Network {
|
|||||||
storeExcessEnergy(availableEnergy);
|
storeExcessEnergy(availableEnergy);
|
||||||
updateHologram(b, supply, demand);
|
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) {
|
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;
|
double supply = 0;
|
||||||
Set<Location> exploded = new HashSet<>();
|
Set<Location> exploded = new HashSet<>();
|
||||||
|
|
||||||
@ -249,7 +257,8 @@ public class EnergyNet extends Network {
|
|||||||
new ErrorReport(t, source, item);
|
new ErrorReport(t, source, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
SlimefunPlugin.getProfiler().closeEntry(source, item, timestamp);
|
long time = SlimefunPlugin.getProfiler().closeEntry(source, item, timestamp);
|
||||||
|
timeCallback.accept(time);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// This block seems to be gone now, better remove it to be extra safe
|
// This block seems to be gone now, better remove it to be extra safe
|
||||||
|
@ -21,7 +21,7 @@ import net.md_5.bungee.api.chat.TextComponent;
|
|||||||
class PerformanceSummary {
|
class PerformanceSummary {
|
||||||
|
|
||||||
// The threshold at which a Block or Chunk is significant enough to appear in /sf timings
|
// 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
|
// 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
|
// 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 float percentage;
|
||||||
|
|
||||||
private final Map<String, Long> chunks;
|
private final Map<String, Long> chunks;
|
||||||
|
private final Map<String, Long> plugins;
|
||||||
private final Map<String, Long> items;
|
private final Map<String, Long> items;
|
||||||
|
|
||||||
PerformanceSummary(SlimefunProfiler profiler, long totalElapsedTime, int totalTickedBlocks) {
|
PerformanceSummary(SlimefunProfiler profiler, long totalElapsedTime, int totalTickedBlocks) {
|
||||||
@ -44,6 +45,7 @@ class PerformanceSummary {
|
|||||||
this.totalTickedBlocks = totalTickedBlocks;
|
this.totalTickedBlocks = totalTickedBlocks;
|
||||||
|
|
||||||
chunks = profiler.getByChunk();
|
chunks = profiler.getByChunk();
|
||||||
|
plugins = profiler.getByPlugin();
|
||||||
items = profiler.getByItem();
|
items = profiler.getByItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,44 +54,47 @@ class PerformanceSummary {
|
|||||||
sender.sendMessage(ChatColor.GREEN + "===== Slimefun Lag Profiler =====");
|
sender.sendMessage(ChatColor.GREEN + "===== Slimefun Lag Profiler =====");
|
||||||
sender.sendMessage(ChatColor.GOLD + "Total: " + ChatColor.YELLOW + NumberUtils.getAsMillis(totalElapsedTime));
|
sender.sendMessage(ChatColor.GOLD + "Total: " + ChatColor.YELLOW + NumberUtils.getAsMillis(totalElapsedTime));
|
||||||
sender.sendMessage(ChatColor.GOLD + "Performance: " + getPerformanceRating());
|
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("");
|
sender.sendMessage("");
|
||||||
|
|
||||||
summarizeTimings("Blocks", sender, entry -> {
|
summarizeTimings(totalTickedBlocks + " Blocks", sender, items, entry -> {
|
||||||
int count = profiler.getBlocksOfId(entry.getKey());
|
int count = profiler.getBlocksOfId(entry.getKey());
|
||||||
String time = NumberUtils.getAsMillis(entry.getValue());
|
String time = NumberUtils.getAsMillis(entry.getValue());
|
||||||
|
|
||||||
if (count > 1) {
|
if (count > 1) {
|
||||||
String average = NumberUtils.getAsMillis(entry.getValue() / count);
|
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 {
|
else {
|
||||||
return entry.getKey() + " - " + count + "x (" + time + ')';
|
return entry.getKey() + " - " + count + "x (" + time + ')';
|
||||||
}
|
}
|
||||||
}, items.entrySet().stream());
|
});
|
||||||
|
|
||||||
sender.sendMessage("");
|
summarizeTimings(chunks.size() + " Chunks", sender, chunks, entry -> {
|
||||||
|
|
||||||
summarizeTimings("Chunks", sender, entry -> {
|
|
||||||
int count = profiler.getBlocksInChunk(entry.getKey());
|
int count = profiler.getBlocksInChunk(entry.getKey());
|
||||||
String time = NumberUtils.getAsMillis(entry.getValue());
|
String time = NumberUtils.getAsMillis(entry.getValue());
|
||||||
|
|
||||||
return entry.getKey() + " - " + count + "x (" + time + ")";
|
return entry.getKey() + " - " + count + "x Blocks (" + time + ")";
|
||||||
}, chunks.entrySet().stream());
|
});
|
||||||
|
|
||||||
|
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());
|
List<Entry<String, Long>> results = stream.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toList());
|
||||||
|
|
||||||
if (sender instanceof Player) {
|
if (sender instanceof Player) {
|
||||||
TextComponent component = new TextComponent(prefix);
|
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.setColor(ChatColor.GRAY);
|
||||||
hoverComponent.setItalic(true);
|
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
int hidden = 0;
|
int hidden = 0;
|
||||||
|
|
||||||
@ -111,11 +116,13 @@ class PerformanceSummary {
|
|||||||
else {
|
else {
|
||||||
int hidden = 0;
|
int hidden = 0;
|
||||||
StringBuilder builder = new StringBuilder();
|
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) {
|
for (Map.Entry<String, Long> entry : results) {
|
||||||
if (entry.getValue() > VISIBILITY_THRESHOLD) {
|
if (entry.getValue() > VISIBILITY_THRESHOLD) {
|
||||||
builder.append(" ");
|
builder.append("\n ");
|
||||||
builder.append(ChatColor.stripColor(formatter.apply(entry)));
|
builder.append(ChatColor.stripColor(formatter.apply(entry)));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -83,10 +83,12 @@ public class SlimefunProfiler {
|
|||||||
* The {@link SlimefunItem} at this {@link Location}
|
* The {@link SlimefunItem} at this {@link Location}
|
||||||
* @param timestamp
|
* @param timestamp
|
||||||
* The timestamp marking the start of this entry, you can retrieve it using {@link #newEntry()}
|
* 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) {
|
if (timestamp == 0) {
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
long elapsedTime = System.nanoTime() - timestamp;
|
long elapsedTime = System.nanoTime() - timestamp;
|
||||||
@ -96,6 +98,8 @@ public class SlimefunProfiler {
|
|||||||
timings.put(block, elapsedTime);
|
timings.put(block, elapsedTime);
|
||||||
queued.decrementAndGet();
|
queued.decrementAndGet();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return elapsedTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -166,6 +170,16 @@ public class SlimefunProfiler {
|
|||||||
return map;
|
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() {
|
protected Map<String, Long> getByChunk() {
|
||||||
Map<String, Long> map = new HashMap<>();
|
Map<String, Long> map = new HashMap<>();
|
||||||
|
|
||||||
@ -208,6 +222,18 @@ public class SlimefunProfiler {
|
|||||||
return blocks;
|
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() {
|
protected float getPercentageOfTick() {
|
||||||
float millis = totalElapsedTime / 1000000.0F;
|
float millis = totalElapsedTime / 1000000.0F;
|
||||||
float fraction = (millis * 100.0F) / PerformanceSummary.MAX_TICK_DURATION;
|
float fraction = (millis * 100.0F) / PerformanceSummary.MAX_TICK_DURATION;
|
||||||
|
Loading…
Reference in New Issue
Block a user