KVFCodec
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user