This commit is contained in:
2026-07-26 22:35:06 +08:00
commit c92cf914fc
58 changed files with 5954 additions and 0 deletions
+129
View File
@@ -0,0 +1,129 @@
package org.kne.debug;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
final class Int implements Comparable<Int>,Cloneable {
public int value;
public Int(int value) {
super();
this.value = value;
}
@Override
public int hashCode() {
return value;
}
@Override
public Object clone() throws CloneNotSupportedException {
// TODO Զɵķ
return super.clone();
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Int other = (Int) obj;
if (value != other.value)
return false;
return true;
}
@Override
public String toString() {
return new Integer(value).toString();
}
@Override
public int compareTo(Int o) {
return o.value-value;
}
}
public class Debuger extends Thread {
Map <List<StackTraceElement>,Object[]>md=new HashMap<List<StackTraceElement>,Object[]>();
@Override
public void run() {
while(true){
for(int iz=0;iz<100;iz++){
Map<Thread, StackTraceElement[]> m=Thread.getAllStackTraces();
Set<Entry<Thread, StackTraceElement[]>> s=m.entrySet();
Iterator<Entry<Thread, StackTraceElement[]>> i=s.iterator();
while(i.hasNext()){
Entry<Thread, StackTraceElement[]>elements =i.next();
StackTraceElement[]value=elements.getValue();
List<StackTraceElement> l=new ArrayList<StackTraceElement>(value.length);
for (int j = 0; j < value.length; j++) {
l.add(value[j]);
}
if(!l.isEmpty())
if(md.containsKey(l)){
((Int)md.get(l)[0]).value++;
}else{
md.put(l,new Object[]{new Int(1),elements.getKey()} );
}
}
}
ArrayList<Entry<List<StackTraceElement>, Object[]>> tmp=new ArrayList();
Set<Entry<List<StackTraceElement>, Object[]>> sn=md.entrySet();
Iterator<Entry<List<StackTraceElement>, Object[]>> in=sn.iterator();
while(in.hasNext()){
Entry<List<StackTraceElement>, Object[]>elements =in.next();
tmp.add(elements);
}
tmp.sort(new Comparator<Entry<List<StackTraceElement>, Object[]>>() {
@Override
public int compare(Entry<List<StackTraceElement>, Object[]> o1,
Entry<List<StackTraceElement>, Object[]> o2) {
return ((Int)o2.getValue()[0]).value-((Int)o1.getValue()[0]).value;
}
});
for(int d=0;d<tmp.size();d++){
Entry<List<StackTraceElement>, Object[]>elements=tmp.get(d);
if(((Thread)(elements.getValue()[1])).getName().startsWith("Decode")){
}else{
continue;
}
List<StackTraceElement> k=elements.getKey();
StringBuilder sb=new StringBuilder();
for(int d2=0;d2<k.size();d2++){
sb.append(' ');sb.append(k.get(d2));
}
System.err.println(elements.getValue()[0]+":"+elements.getValue()[1]+"="+sb);
}
System.err.println("--------------------------------------------------------------------------------------------------------------------");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Զɵ catch
e.printStackTrace();
}
}
}
}
+180
View File
@@ -0,0 +1,180 @@
package org.kne.debug;
import java.util.ArrayList;
import java.util.List;
/**
* 高性能插桩计时器
* 用于在代码中插入时间测量点,输出各阶段耗时
*
* 用法:
* private static final boolean DEBUG = false; // 生产环境关掉
* TimeDebugger td = new TimeDebugger("编码流程", DEBUG);
* td.mark("读取图片");
* // ... 读取图片代码 ...
* td.mark("预测");
* // ... 预测代码 ...
* td.mark("压缩");
* // ... 压缩代码 ...
* td.print();
*
* 当 DEBUG = false 时,所有方法调用被 JIT 优化为空操作,零开销
*/
public final class TimeDebugger {
private final boolean enabled;
private final String name;
private final List<TimingPoint> points;
private long lastNanoTime;
private long startNanoTime;
/**
* 创建一个计时器
* @param name 本次测量的名称(用于输出标题)
* @param enabled true=启用计时,false=所有操作跳过(零开销)
*/
public TimeDebugger(String name, boolean enabled) {
this.enabled = enabled;
this.name = name;
// enabled=false 时不分配 ArrayList 内存
this.points = enabled ? new ArrayList<>() : null;
if (enabled) {
this.lastNanoTime = System.nanoTime();
this.startNanoTime = this.lastNanoTime;
} else {
this.lastNanoTime = 0;
this.startNanoTime = 0;
}
}
/**
* 标记一个时间点
* @param label 当前阶段的名称
*/
public void mark(String label) {
if (!enabled) return;
long now = System.nanoTime();
long durationNs = now - lastNanoTime;
lastNanoTime = now;
points.add(new TimingPoint(label, durationNs));
}
/**
* 标记一个时间点,并打印到控制台(实时输出,方便跟踪长流程)
* @param label 当前阶段的名称
*/
public void markAndPrint(String label) {
if (!enabled) return;
mark(label);
System.out.printf(" ⏱️ %s: %.3fms\n", label, getLastDurationMs());
}
/**
* 获取上一个阶段的耗时(毫秒)
*/
public double getLastDurationMs() {
if (!enabled || points.isEmpty()) return 0;
return points.get(points.size() - 1).durationMs();
}
/**
* 获取总耗时(毫秒)
*/
public double getTotalMs() {
if (!enabled) return 0;
return (lastNanoTime - startNanoTime) / 1_000_000.0;
}
/**
* 打印所有计时结果
*/
public void print() {
if (!enabled) return;
StringBuilder sb = new StringBuilder();
sb.append("═══════════════════════════════════════════════\n");
sb.append(" ⏱️ ").append(name).append("\n");
sb.append("═══════════════════════════════════════════════\n");
double total = 0;
for (int i = 0; i < points.size(); i++) {
TimingPoint p = points.get(i);
double ms = p.durationMs();
total += ms;
sb.append(String.format(" %-20s: %8.3fms (累计: %8.3fms)\n",
p.label, ms, total));
}
sb.append("───────────────────────────────────────────────\n");
sb.append(String.format(" %-20s: %8.3fms\n", "总计", total));
sb.append("═══════════════════════════════════════════════");
System.err.println(sb.toString());
}
/**
* 重置计时器(不清除已有记录,用于分段测量)
*/
public void reset() {
if (!enabled) return;
this.lastNanoTime = System.nanoTime();
this.startNanoTime = this.lastNanoTime;
if (points != null) {
this.points.clear();
}
}
/**
* 检查是否启用
*/
public boolean isEnabled() {
return enabled;
}
/**
* 内部计时点
*/
private static final class TimingPoint {
final String label;
final long durationNs;
TimingPoint(String label, long durationNs) {
this.label = label;
this.durationNs = durationNs;
}
double durationMs() {
return durationNs / 1_000_000.0;
}
}
// ==================== 静态方法:全局默认实例 ====================
private static TimeDebugger defaultDebugger;
/**
* 获取全局默认计时器(简化用法,不需要 new)
* 默认启用,如需关闭请使用 get(boolean)
*/
public static TimeDebugger get() {
return get(true);
}
/**
* 获取全局默认计时器(可指定开关)
* @param enabled true=启用,false=关闭
*/
public static TimeDebugger get(boolean enabled) {
if (defaultDebugger == null || defaultDebugger.isEnabled() != enabled) {
defaultDebugger = new TimeDebugger("默认流程", enabled);
}
return defaultDebugger;
}
/**
* 重置全局默认计时器
*/
public static void resetDefault() {
if (defaultDebugger != null) {
defaultDebugger.reset();
}
}
}