正常情况下,我们如果需要看某段代码的执行耗时,会通过如下的方式进行查看:
// 放在要检测的代码段前,取开始前的时间戳 Long startTime = System.currentTimeMillis(); // 放在要检测的代码段后,取结束后的时间戳 Long endTime = System.currentTimeMillis(); logger.info("#####################调用总耗时"+ (endTime-startTime));
例子
public class Demo015 { public static void main(String[] args) throws InterruptedException { test0(); } public static void test0() throws InterruptedException { long start = System.currentTimeMillis(); // do something Thread.sleep(100); long end = System.currentTimeMillis(); System.out.println("某某1执行耗时:" + (end - start)); } }
结果:
某某1执行耗时:111
该种方法通过获取执行完成时间与执行开始时间的差值得到程序的执行时间,简单直接有效,但想必写多了也是比较烦人的。
首先我们的需求如下:
- 记录开始时间点
- 记录结束时间点
- 输出执行时间及各个时间段的占比
根据该需求,我们可直接使用org.springframework.util包下的一个工具类StopWatch,通过该工具类,我们对上述代码做如下改造:
1)、引入依赖
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.2.10.RELEASE</version> </dependency>
2)、测试类
public class Demo015 { public static void main(String[] args) throws InterruptedException { test1(); } public static void test1() throws InterruptedException { StopWatch sw = new StopWatch("test"); sw.start("task1"); // do something Thread.sleep(100); sw.stop(); sw.start("task2"); // do something Thread.sleep(200); sw.stop(); System.out.println(sw.prettyPrint()); System.out.println(sw.shortSummary()); System.out.println(sw.getTotalTimeMillis()); } }
注意:getTotalTimeMillis方法得到总耗时。
结果:
StopWatch 'test': running time = 314005800 ns --------------------------------------------- ns % Task name --------------------------------------------- 113457300 036% task1 200548500 064% task2 StopWatch 'test': running time = 314005800 ns 314
start开始记录,stop停止记录,然后通过StopWatch的prettyPrint方法,可直观的输出代码执行耗时,以及执行时间百分比。
除此之外,还有以下两个方法shortSummary,getTotalTimeMillis,查看程序执行时间。
StopWatch优缺点:
优点:
1)、spring自带工具类,可直接使用
2)、代码实现简单,使用更简单
3)、统一归纳,展示每项任务耗时与占用总时间的百分比,展示结果直观性能消耗相对较小,并且最大程度的保证了start与stop之间的时间记录的准确性
4)、可在start时直接指定任务名字,从而更加直观的显示记录结果
缺点:
1)、一个StopWatch实例一次只能开启一个task,不能同时start多个task,并且在该task未stop之前不能start一个新的task,必须在该task stop之后才能开启新的task,若要一次开启多个,需要new不同的StopWatch实例
2)、代码侵入式使用,需要改动多处代码