作为一名程序猿,有时为了查看代码执行效率,以下代码肯定不少写:
long start = System.currentTimeMillis();
// do something...
long end = System.currentTimeMillis();
System.out.println(start-end);
上面这段代码,只要是个java程序猿肯定都写过,问题是写个一两次还可以忍受,但是要针对复杂逻辑代码进行性能分析的时候,此时需要些大量的计时代码,你就无法忍受了。各位猿不要急,spring给我们提供一个工具类StopWatch,这货就是专门干计时的,但在使用的时候最好还是封装下,话不多说上代码:
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StopWatch;
public class StopWatchTool
{
private static final Logger LOGGER = LoggerFactory.getLogger(StopWatchTool.class);
private static final ThreadLocal<String> localId = new ThreadLocal<String>();
private static final ThreadLocal<Map<String, Map<String, StopWatch>>> localWatchs = new ThreadLocal<Map<String, Map<String, StopWatch>>>();
private static Map<String, Map<String, StopWatch>> a() {
Map<String, Map<String, StopWatch>> map;
if (localWatchs.get() == null) {
map = new ConcurrentHashMap<String, Map<String, StopWatch>>();
localWatchs.set(map);
} else {
map = localWatchs.get();
}
return map;
}
private static Map<String, StopWatch> a(String paramString) {
LinkedHashMap<String, StopWatch> linkedHashMap;
Map<String, Map<String, StopWatch>> map;
if ((map = a()).containsKey(paramString)) {
linkedHashMap = (LinkedHashMap<String, StopWatch>)map.get(paramString);
} else {
linkedHashMap = new LinkedHashMap<String, StopWatch>();
map.put(paramString, linkedHashMap);
}
return (Map<String, StopWatch>)linkedHashMap;
}
private static StopWatch a(String paramString1, String paramString2) {
StopWatch stopWatch;
Map<String, StopWatch> map;
if ((map = a(paramString1)).containsKey(paramString2)) {
stopWatch = map.get(paramString2);
} else {
stopWatch = new StopWatch(getId());
map.put(paramString2, stopWatch);
}
return stopWatch;
}
public static void stopAndStartNew(String paramString1, String paramString2, String paramString3) {
stop(paramString1, paramString2);
start(paramString1, paramString2, paramString3);
}
public static void start(String paramString1, String paramString2, String paramString3) { a(paramString1, paramString2).start(getId() + ":" + paramString3); }
public static void stop(String paramString1, String paramString2) {
StopWatch stopWatch;
if ((stopWatch = a(paramString1, paramString2)).isRunning()) {
stopWatch.stop();
}
}
public static void print(String paramString) {
Iterator<?> iterator = a(paramString).entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry)iterator.next();
print(paramString, (String)entry.getKey(), false);
}
a().remove(paramString);
}
public static void print(String paramString1, String paramString2) { print(paramString1, paramString2, true); }
public static void print(String paramString1, String paramString2, boolean paramBoolean) {
StopWatch stopWatch;
if ((stopWatch = a(paramString1, paramString2)).isRunning()) {
stopWatch.stop();
}
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("###### watch key: {}, step: {}, pretty: {}", new Object[] { paramString1, paramString2, stopWatch.prettyPrint() });
}
if (paramBoolean) {
a(paramString1).remove(paramString2);
}
}
public static void setId(String paramString) { localId.set(paramString); }
public static String getId() { return localId.get(); }
public static void cleanId() { localId.remove(); }
public static void cleanWatch() { localWatchs.remove(); }
}
这里将StopWatch简单封装了下,作为一个工具使用,具体使用方式如下:
StopWatchTool.stopAndStartNew("XXXController类", "XXX方法名", "XXX标记处1");
.....
StopWatchTool.stopAndStartNew("XXXController类", "XXX方法名", "XXX标记处2");
......
StopWatchTool.stopAndStartNew("XXXController类", "XXX方法名", "XXX标记处3");
....
StopWatchTool.print("XXXController类", "XXX方法名"); //打印计时log