Commons-lang3提供的StopWatch执行时间监视器, spring也提供了同样功能的工具
前言
我们如果要统计一段代码的执行时间:我们的办法是
public static void main(String[] args) {
long startTime=System.currentTimeMillis(); //获取开始时间
//函数主体代码
//...
long endTime=System.currentTimeMillis(); //获取结束时间
System.out.println("程序运行时间: "+(endTime-startTime)+"ms");
}
倘若我们要展示成秒、甚至分钟,还得我们自己处理
可能到了JDK8以后,我们变得稍微优雅一些了 可以这么处理:
Instant start = Instant.now();
//doSomething();
Instant end = Instant.now();
Duration duration = Duration.between(start, end);
System.out.println("millis = " + duration.toMillis());
这个比上面优雅一点,灵活度也更强一些。但定义的变量有点多,总体上还是不够优雅。因此本文介绍StopWatch执行时间监视器,来统计我们程序的执行时间,非常多的方便和优雅。
StopWatch:执行时间监视器
StopWatch有很多开源的框架都有提供类似的功能。比如Apache的commons-lang3,还有Spring framwork自己都有提供。
但本文只介绍lang3里面的,功能上大同小异。而且Apache提供的功能强大,并且lang3包一般是我们必导的包,但spring的就不一定了(比如纯java项目,是不用导入spring包的),lang3的功用性也更强些。
public static void main(String[] args) throws Exception {
StopWatch watch = StopWatch.createStarted(); //创建后立即start,常用
//StopWatch watch = new StopWatch();
//watch.start();
Thread.sleep(1000);
System.out.println("统计从开始到现在运行时间:" + watch.getTime() + "ms"); //1000ms
Thread.sleep(1000);
watch.split();
System.out.println("从start到此刻为止的时间:" + watch.getTime());
System.out.println("从开始到第一个切入点运行时间:" + watch.getSplitTime()); //2245
Thread.sleep(1000);
watch.split();
System.out.println("从开始到第二个切入点运行时间:" + watch.getSplitTime());
watch.reset(); //重置后必须使用start方法
watch.start();
Thread.sleep(1000);
System.out.println("重新开始后到当前运行时间是:" + watch.getTime()); //1000
watch.suspend(); //暂停
Thread.sleep(6000); //模拟暂停6秒钟
watch.resume(); //上面suspend,这里要想重新统计,需要恢复一下
System.out.println("恢复后执行的时间是:" + watch.getTime()); //1000 注意此时这个值还是1000
watch.stop();
System.out.println("花费的时间》》" + watch.getTime() + "ms"); //1002ms
System.out.println("花费的时间》》" + watch.getTime(TimeUnit.SECONDS) + "s"); //1s 可以直接转成s
}
如上就是StopWatch的基本使用方法。
StopWatch的使用细节
getTime和getSplitTime有啥区别呢?
此处我们看看getNanoTime()和getSplitNanoTime()即可
public long getNanoTime() {
if (this.runningState == State.STOPPED || this.runningState == State.SUSPENDED) {
return this.stopTime - this.startTime;
} else if (this.runningState == State.UNSTARTED) {
return 0;
} else if (this.runningState == State.RUNNING) {
return System.nanoTime() - this.startTime;
}
throw new RuntimeException("Illegal running state has occurred.");
}
public long getSplitNanoTime() {
if (this.splitState != SplitState.SPLIT) {
throw new IllegalStateException("Stopwatch must be split to get the split time. ");
}
return this.stopTime - this.startTime;
}
我们发现:
- 调用getSplit相关方法前,必须调用Split方法
spilit()方法源码如下:
public void split() {
if (this.runningState != State.RUNNING) {
throw new IllegalStateException("Stopwatch is not running. ");
}
this.stopTime = System.nanoTime();
this.splitState = SplitState.SPLIT;
}
我们发现调用split方法后,watch的状态改为了SPLIT。**且,且,且stopTime 设置为了当前时间。**因此此处我们的stopTime禁止了,这个时候调用getSplitNanoTime,用stopTime减去startTime即可。因此用此方法可以插入先停止stopTime,最后再输出。
而getTime()就是拿当前的时间戳,减去startTime,一般不涉及到stopTime的值,因此splitTime处理计算时间显然更加的灵活,但是,一般我们使用getTime()就足够了
最后
很多时候,写代码也是一种艺术。希望我们能有追求更加美好事物的心,这点对于接纳新知识特别重要。因此此处推荐这个监视器来代替之前的的使用,能让我们更加灵活的控制程序代码。
来源:oschina
链接:https://my.oschina.net/u/854444/blog/3066177