作为一名程序猿,有时为了查看代码执行效率,以下代码肯定不少写:
long start = System.currentTimeMillis();
// do something…
long end = System.currentTimeMillis();
System.out.println(start-end);
上面这段代码,只要是个java程序猿肯定都写过,问题是写个一两次还可以忍受,但是要针对复杂逻辑代码进行性能分析的时候,此时需要些大量的计时代码,你就无法忍受了。各位猿不要急,spring给我们提供一个工具类StopWatch,这货就是专门干计时的,但在使用的时候最好还是封装下,话不多说上代码:
package com.ywy.springboot.testspringboot.util;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StopWatch;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 计时工具类
*/
// @Slf4j(topic = "log.StopWatchUtil")
public class StopWatchUtil {
private static final Logger log = LoggerFactory.getLogger(StopWatchUtil.class);
private static final ThreadLocal<String> localId = new ThreadLocal<String>();
private static final ThreadLocal<Map<String, Map<String, StopWatch>>> localWatchs = new ThreadLocal<>();
public static void stopAndStartNew(String key1, String key2, String p){
stop(key1, key2);
start(key1, key2, p);
}
public static void start(String key1, String key2, String p){
p = StrUtil.builder()
.append(getId())
.append(":")
.append(p).toString();
a(key1, key2).start(p);
}
public static void stop(String key1, String key2){
StopWatch stopWatch;
if ((stopWatch = a(key1, key2)).isRunning()) {
stopWatch.stop();
}
}
private static Map<String, Map<String, StopWatch>> a(){
Map<String, Map<String, StopWatch>> map;
if (localWatchs.get() == null) {
map = new ConcurrentHashMap<>();
localWatchs.set(map);
}
return localWatchs.get();
}
private static Map<String, StopWatch> a(String key){
LinkedHashMap<String, StopWatch> linkedHashMap;
Map<String, Map<String, StopWatch>> map;
if ((map = a()).containsKey(key)) {
return map.get(key);
}
linkedHashMap = new LinkedHashMap<>();
map.put(key, linkedHashMap);
return linkedHashMap;
}
private static StopWatch a(String key1, String key2){
StopWatch stopWatch;
Map<String, StopWatch> map;
if ((map = a(key1)).containsKey(key2)) {
return map.get(key2);
}
stopWatch = new StopWatch(getId());
map.put(key2, stopWatch);
return stopWatch;
}
public static void print(String key) {
Iterator<Map.Entry<String, StopWatch>> iterator = a(key).entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, StopWatch> next = iterator.next();
print(key, next.getKey(), false);
}
a().remove(key);
}
public static void print(String key1, String key2){
print(key1, key2, true);
}
private static void print(String key1, String key2, boolean bool) {
StopWatch stopWatch;
if ((stopWatch = a(key1, key2)).isRunning()) {
stopWatch.stop();
}
if (log.isTraceEnabled()) {
log.trace("###### watch key: {}, step: {}, pretty: {}", key1, key2, stopWatch.prettyPrint());
}
if (bool) {
a(key1).remove(key2);
}
}
public static void setId(String id){
localId.set(id);
}
public static String getId() {
return localId.get();
}
public static void clearId(){
localId.remove();
}
public static void clearWatch(){
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