背景
最近看到现在的项目里,有的程序员很负责,对自己写的代码性能如何很上心,会有很多这样的代码:
long start = new Date().getTime();
//业务逻辑
long end = new Date().getTime();
system.out.println("耗时:" + (end - start) + "毫秒");
其实可以用StopWatch,更优雅,更何况springboot启动的时候,打印的耗时就是用StopWatch。
示例
springboot启动源码
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
this.configureHeadlessProperty();
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting();
Collection exceptionReporters;
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
this.configureIgnoreBeanInfo(environment);
Banner printedBanner = this.printBanner(environment);
context = this.createApplicationContext();
exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}
listeners.started(context);
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {
this.handleRunFailure(context, var10, exceptionReporters, listeners);
throw new IllegalStateException(var10);
}
try {
listeners.running(context);
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}
统计输出总耗时
public class SpringStopWatchExample {
public static void main (String[] args) throws InterruptedException {
StopWatch sw = new StopWatch();
sw.start();
//long task simulation
Thread.sleep(1000);
sw.stop();
System.out.println(sw.getTotalTimeMillis());
}
}
输出最后一个任务的耗时
public class SpringStopWatchExample2 {
public static void main (String[] args) throws InterruptedException {
StopWatch sw = new StopWatch();
sw.start("A");//setting a task name
//long task simulation
Thread.sleep(1000);
sw.stop();
System.out.println(sw.getLastTaskTimeMillis());
}
}
以优雅的格式打出所有任务的耗时以及占比
public class SpringStopWatchExample3 {
public static void main (String[] args) throws InterruptedException {
StopWatch sw = new StopWatch();
sw.start("A");
Thread.sleep(500);
sw.stop();
sw.start("B");
Thread.sleep(300);
sw.stop();
sw.start("C");
Thread.sleep(200);
sw.stop();
System.out.println(sw.prettyPrint());
}
}
输出:
StopWatch '': running time (millis) = 1031
-----------------------------------------
ms % Task name
-----------------------------------------
00514 050% A
00302 029% B
00215 021% C
不同的打印结果
- getTotalTimeSeconds() 获取总耗时秒,同时也有获取毫秒的方法
- prettyPrint() 优雅的格式打印结果,表格形式
- shortSummary() 返回简短的总耗时描述
- getTaskCount() 返回统计时间任务的数量
- getLastTaskInfo().getTaskName() 返回最后一个任务TaskInfo对象的名称
- https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/util/StopWatch.html