FilledProfileResults.java
net.minecraft.util.profiling.FilledProfileResults
信息
- 全限定名:net.minecraft.util.profiling.FilledProfileResults
- 类型:public class
- 包:net.minecraft.util.profiling
- 源码路径:src/main/java/net/minecraft/util/profiling/FilledProfileResults.java
- 起始行号:L26
- 实现:ProfileResults
- 职责:
TODO
字段/常量
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L27 - 说明:
TODO
- 类型:
-
EMPTY- 类型:
ProfilerPathEntry - 修饰符:
private static final public public public public - 源码定位:
L28 - 说明:
TODO
- 类型:
-
SPLITTER- 类型:
Splitter - 修饰符:
private static final - 源码定位:
L49 - 说明:
TODO
- 类型:
-
COUNTER_ENTRY_COMPARATOR- 类型:
Comparator<Entry<String,FilledProfileResults.CounterCollector>> - 修饰符:
private static final - 源码定位:
L50 - 说明:
TODO
- 类型:
-
entries- 类型:
Map<String,?extends ProfilerPathEntry> - 修饰符:
private final - 源码定位:
L54 - 说明:
TODO
- 类型:
-
startTimeNano- 类型:
long - 修饰符:
private final - 源码定位:
L55 - 说明:
TODO
- 类型:
-
startTimeTicks- 类型:
int - 修饰符:
private final - 源码定位:
L56 - 说明:
TODO
- 类型:
-
endTimeNano- 类型:
long - 修饰符:
private final - 源码定位:
L57 - 说明:
TODO
- 类型:
-
endTimeTicks- 类型:
int - 修饰符:
private final - 源码定位:
L58 - 说明:
TODO
- 类型:
-
tickDuration- 类型:
int - 修饰符:
private final - 源码定位:
L59 - 说明:
TODO
- 类型:
内部类/嵌套类型
net.minecraft.util.profiling.FilledProfileResults.CounterCollector- 类型:
class - 修饰符:
private static - 源码定位:
L301 - 说明:
TODO
- 类型:
构造器
public FilledProfileResults(Map<String,?extends ProfilerPathEntry> entries, long startTimeNano, int startTimeTicks, long endTimeNano, int endTimeTicks) @ L61
- 构造器名:FilledProfileResults
- 源码定位:L61
- 修饰符:public
参数:
- entries: Map<String,?extends ProfilerPathEntry>
- startTimeNano: long
- startTimeTicks: int
- endTimeNano: long
- endTimeTicks: int
说明:
TODO
方法
下面的方法块按源码顺序生成。
private ProfilerPathEntry getEntry(String path) @ L70
- 方法名:getEntry
- 源码定位:L70
- 返回类型:ProfilerPathEntry
- 修饰符:private
参数:
- path: String
说明:
TODO
public List<ResultField> getTimes(String path) @ L75
- 方法名:getTimes
- 源码定位:L75
- 返回类型:List
- 修饰符:public
参数:
- path: String
说明:
TODO
private static boolean isDirectChild(String path, String test) @ L127
- 方法名:isDirectChild
- 源码定位:L127
- 返回类型:boolean
- 修饰符:private static
参数:
- path: String
- test: String
说明:
TODO
private Map<String,FilledProfileResults.CounterCollector> getCounterValues() @ L131
- 方法名:getCounterValues
- 源码定位:L131
- 返回类型:Map<String,FilledProfileResults.CounterCollector>
- 修饰符:private
参数:
- 无
说明:
TODO
public long getStartTimeNano() @ L149
- 方法名:getStartTimeNano
- 源码定位:L149
- 返回类型:long
- 修饰符:public
参数:
- 无
说明:
TODO
public int getStartTimeTicks() @ L154
- 方法名:getStartTimeTicks
- 源码定位:L154
- 返回类型:int
- 修饰符:public
参数:
- 无
说明:
TODO
public long getEndTimeNano() @ L159
- 方法名:getEndTimeNano
- 源码定位:L159
- 返回类型:long
- 修饰符:public
参数:
- 无
说明:
TODO
public int getEndTimeTicks() @ L164
- 方法名:getEndTimeTicks
- 源码定位:L164
- 返回类型:int
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean saveResults(Path file) @ L169
- 方法名:saveResults
- 源码定位:L169
- 返回类型:boolean
- 修饰符:public
参数:
- file: Path
说明:
TODO
protected String getProfilerResults(long timespan, int tickspan) @ L189
- 方法名:getProfilerResults
- 源码定位:L189
- 返回类型:String
- 修饰符:protected
参数:
- timespan: long
- tickspan: int
说明:
TODO
public String getProfilerResults() @ L213
- 方法名:getProfilerResults
- 源码定位:L213
- 返回类型:String
- 修饰符:public
参数:
- 无
说明:
TODO
private static StringBuilder indentLine(StringBuilder builder, int depth) @ L220
- 方法名:indentLine
- 源码定位:L220
- 返回类型:StringBuilder
- 修饰符:private static
参数:
- builder: StringBuilder
- depth: int
说明:
TODO
private void appendProfilerResults(int depth, String path, StringBuilder builder) @ L230
- 方法名:appendProfilerResults
- 源码定位:L230
- 返回类型:void
- 修饰符:private
参数:
- depth: int
- path: String
- builder: StringBuilder
说明:
TODO
private void appendCounterResults(int depth, String name, FilledProfileResults.CounterCollector result, int tickspan, StringBuilder builder) @ L269
- 方法名:appendCounterResults
- 源码定位:L269
- 返回类型:void
- 修饰符:private
参数:
- depth: int
- name: String
- result: FilledProfileResults.CounterCollector
- tickspan: int
- builder: StringBuilder
说明:
TODO
private void appendCounters(Map<String,FilledProfileResults.CounterCollector> counters, StringBuilder builder, int tickspan) @ L288
- 方法名:appendCounters
- 源码定位:L288
- 返回类型:void
- 修饰符:private
参数:
- counters: Map<String,FilledProfileResults.CounterCollector>
- builder: StringBuilder
- tickspan: int
说明:
TODO
public int getTickDuration() @ L296
- 方法名:getTickDuration
- 源码定位:L296
- 返回类型:int
- 修饰符:public
参数:
- 无
说明:
TODO
代码
public class FilledProfileResults implements ProfileResults {
private static final Logger LOGGER = LogUtils.getLogger();
private static final ProfilerPathEntry EMPTY = new ProfilerPathEntry() {
@Override
public long getDuration() {
return 0L;
}
@Override
public long getMaxDuration() {
return 0L;
}
@Override
public long getCount() {
return 0L;
}
@Override
public Object2LongMap<String> getCounters() {
return Object2LongMaps.emptyMap();
}
};
private static final Splitter SPLITTER = Splitter.on('\u001e');
private static final Comparator<Entry<String, FilledProfileResults.CounterCollector>> COUNTER_ENTRY_COMPARATOR = Entry.<String, FilledProfileResults.CounterCollector>comparingByValue(
Comparator.comparingLong(c -> c.totalValue)
)
.reversed();
private final Map<String, ? extends ProfilerPathEntry> entries;
private final long startTimeNano;
private final int startTimeTicks;
private final long endTimeNano;
private final int endTimeTicks;
private final int tickDuration;
public FilledProfileResults(Map<String, ? extends ProfilerPathEntry> entries, long startTimeNano, int startTimeTicks, long endTimeNano, int endTimeTicks) {
this.entries = entries;
this.startTimeNano = startTimeNano;
this.startTimeTicks = startTimeTicks;
this.endTimeNano = endTimeNano;
this.endTimeTicks = endTimeTicks;
this.tickDuration = endTimeTicks - startTimeTicks;
}
private ProfilerPathEntry getEntry(String path) {
ProfilerPathEntry result = this.entries.get(path);
return result != null ? result : EMPTY;
}
@Override
public List<ResultField> getTimes(String path) {
String rawPath = path;
ProfilerPathEntry rootEntry = this.getEntry("root");
long globalTime = rootEntry.getDuration();
ProfilerPathEntry currentEntry = this.getEntry(path);
long selfTime = currentEntry.getDuration();
long selfCount = currentEntry.getCount();
List<ResultField> result = Lists.newArrayList();
if (!path.isEmpty()) {
path = path + "\u001e";
}
long totalTime = 0L;
for (String key : this.entries.keySet()) {
if (isDirectChild(path, key)) {
totalTime += this.getEntry(key).getDuration();
}
}
float oldTime = (float)totalTime;
if (totalTime < selfTime) {
totalTime = selfTime;
}
if (globalTime < totalTime) {
globalTime = totalTime;
}
for (String keyx : this.entries.keySet()) {
if (isDirectChild(path, keyx)) {
ProfilerPathEntry entry = this.getEntry(keyx);
long time = entry.getDuration();
double timePercentage = time * 100.0 / totalTime;
double globalPercentage = time * 100.0 / globalTime;
String name = keyx.substring(path.length());
result.add(new ResultField(name, timePercentage, globalPercentage, entry.getCount()));
}
}
if ((float)totalTime > oldTime) {
result.add(
new ResultField("unspecified", ((float)totalTime - oldTime) * 100.0 / totalTime, ((float)totalTime - oldTime) * 100.0 / globalTime, selfCount)
);
}
Collections.sort(result);
result.add(0, new ResultField(rawPath, 100.0, totalTime * 100.0 / globalTime, selfCount));
return result;
}
private static boolean isDirectChild(String path, String test) {
return test.length() > path.length() && test.startsWith(path) && test.indexOf(30, path.length() + 1) < 0;
}
private Map<String, FilledProfileResults.CounterCollector> getCounterValues() {
Map<String, FilledProfileResults.CounterCollector> result = Maps.newTreeMap();
this.entries
.forEach(
(path, entry) -> {
Object2LongMap<String> counters = entry.getCounters();
if (!counters.isEmpty()) {
List<String> pathSegments = SPLITTER.splitToList(path);
counters.forEach(
(counter, value) -> result.computeIfAbsent(counter, k -> new FilledProfileResults.CounterCollector())
.addValue(pathSegments.iterator(), value)
);
}
}
);
return result;
}
@Override
public long getStartTimeNano() {
return this.startTimeNano;
}
@Override
public int getStartTimeTicks() {
return this.startTimeTicks;
}
@Override
public long getEndTimeNano() {
return this.endTimeNano;
}
@Override
public int getEndTimeTicks() {
return this.endTimeTicks;
}
@Override
public boolean saveResults(Path file) {
Writer writer = null;
boolean var4;
try {
Files.createDirectories(file.getParent());
writer = Files.newBufferedWriter(file, StandardCharsets.UTF_8);
writer.write(this.getProfilerResults(this.getNanoDuration(), this.getTickDuration()));
return true;
} catch (Throwable var8) {
LOGGER.error("Could not save profiler results to {}", file, var8);
var4 = false;
} finally {
IOUtils.closeQuietly(writer);
}
return var4;
}
protected String getProfilerResults(long timespan, int tickspan) {
StringBuilder builder = new StringBuilder();
ReportType.PROFILE.appendHeader(builder, List.of());
builder.append("Version: ").append(SharedConstants.getCurrentVersion().id()).append('\n');
builder.append("Time span: ").append(timespan / 1000000L).append(" ms\n");
builder.append("Tick span: ").append(tickspan).append(" ticks\n");
builder.append("// This is approximately ")
.append(String.format(Locale.ROOT, "%.2f", tickspan / ((float)timespan / 1.0E9F)))
.append(" ticks per second. It should be ")
.append(20)
.append(" ticks per second\n\n");
builder.append("--- BEGIN PROFILE DUMP ---\n\n");
this.appendProfilerResults(0, "root", builder);
builder.append("--- END PROFILE DUMP ---\n\n");
Map<String, FilledProfileResults.CounterCollector> counters = this.getCounterValues();
if (!counters.isEmpty()) {
builder.append("--- BEGIN COUNTER DUMP ---\n\n");
this.appendCounters(counters, builder, tickspan);
builder.append("--- END COUNTER DUMP ---\n\n");
}
return builder.toString();
}
@Override
public String getProfilerResults() {
StringBuilder builder = new StringBuilder();
this.appendProfilerResults(0, "root", builder);
return builder.toString();
}
private static StringBuilder indentLine(StringBuilder builder, int depth) {
builder.append(String.format(Locale.ROOT, "[%02d] ", depth));
for (int j = 0; j < depth; j++) {
builder.append("| ");
}
return builder;
}
private void appendProfilerResults(int depth, String path, StringBuilder builder) {
List<ResultField> results = this.getTimes(path);
Object2LongMap<String> counters = ObjectUtils.firstNonNull(this.entries.get(path), EMPTY).getCounters();
counters.forEach(
(id, value) -> indentLine(builder, depth)
.append('#')
.append(id)
.append(' ')
.append(value)
.append('/')
.append(value / this.tickDuration)
.append('\n')
);
if (results.size() >= 3) {
for (int i = 1; i < results.size(); i++) {
ResultField result = results.get(i);
indentLine(builder, depth)
.append(result.name)
.append('(')
.append(result.count)
.append('/')
.append(String.format(Locale.ROOT, "%.0f", (float)result.count / this.tickDuration))
.append(')')
.append(" - ")
.append(String.format(Locale.ROOT, "%.2f", result.percentage))
.append("%/")
.append(String.format(Locale.ROOT, "%.2f", result.globalPercentage))
.append("%\n");
if (!"unspecified".equals(result.name)) {
try {
this.appendProfilerResults(depth + 1, path + "\u001e" + result.name, builder);
} catch (Exception var9) {
builder.append("[[ EXCEPTION ").append(var9).append(" ]]");
}
}
}
}
}
private void appendCounterResults(int depth, String name, FilledProfileResults.CounterCollector result, int tickspan, StringBuilder builder) {
indentLine(builder, depth)
.append(name)
.append(" total:")
.append(result.selfValue)
.append('/')
.append(result.totalValue)
.append(" average: ")
.append(result.selfValue / tickspan)
.append('/')
.append(result.totalValue / tickspan)
.append('\n');
result.children
.entrySet()
.stream()
.sorted(COUNTER_ENTRY_COMPARATOR)
.forEach(e -> this.appendCounterResults(depth + 1, e.getKey(), e.getValue(), tickspan, builder));
}
private void appendCounters(Map<String, FilledProfileResults.CounterCollector> counters, StringBuilder builder, int tickspan) {
counters.forEach((counter, counterRoot) -> {
builder.append("-- Counter: ").append(counter).append(" --\n");
this.appendCounterResults(0, "root", counterRoot.children.get("root"), tickspan, builder);
builder.append("\n\n");
});
}
@Override
public int getTickDuration() {
return this.tickDuration;
}
private static class CounterCollector {
private long selfValue;
private long totalValue;
private final Map<String, FilledProfileResults.CounterCollector> children = Maps.newHashMap();
public void addValue(Iterator<String> path, long value) {
this.totalValue += value;
if (!path.hasNext()) {
this.selfValue += value;
} else {
this.children.computeIfAbsent(path.next(), k -> new FilledProfileResults.CounterCollector()).addValue(path, value);
}
}
}
}引用的其他类
-
- 引用位置:
方法调用 - 关联成员:
SharedConstants.getCurrentVersion()
- 引用位置:
-
- 引用位置:
实现
- 引用位置:
-
- 引用位置:
参数/字段/构造调用/返回值 - 关联成员:
ProfilerPathEntry()
- 引用位置:
-
- 引用位置:
构造调用/返回值 - 关联成员:
ResultField()
- 引用位置: