统计java代码执行耗时的N种方案

平时的开发中,偶尔会遇到统计代码执行耗时的情况,一般代码如下:

1
2
3
4
5
long start = System.currentTimeMillis();

// .....代码段

System.out.println("cost time: " + (System.currentTimeMillis() - start) + " ms");

如果为了防止异常,可以这么写:

1
2
3
4
5
6
7
8
long start = System.currentTimeMillis();
try {

// .....代码段

} finally {
System.out.println("cost time: " + (System.currentTimeMillis() - start) + " ms");
}

如上写法也没啥问题,就是单纯的统计耗时, 下面再列举其他的统计耗时的写法。

1、Spring AOP

spring aop使用切面可以无侵入的统计方法执行耗时,不过此种方式只针对统计方法级别的耗时。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 定义切点,拦截所有满足条件的方法
*/
@Pointcut("execution(public * com.example.aop.*.*(*))")
public void point() {
}

@Around("point()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
try{
return joinPoint.proceed();
} finally {
System.out.println("cost time: " + (System.currentTimeMillis() - start) + " ms");
}
}

2、StopWatch

StopWatch 是Spring框架util包下工具类(org.springframework.util.StopWatch)。

1
2
3
4
5
StopWatch stopWatch = new StopWatch();
stopWatch.start();
// .....代码段
stopWatch.stop();
System.out.println("cost time: " + stopWatch.getTotalTimeMillis() + " ms");

3、Duration

Duration对象表示两个Instant间的一段时间,是在Java 8中加入的新功能。

1
2
3
4
Instant start = Instant.now();
// .....代码段
Instant end = Instant.now();
System.out.println("cost time: " + Duration.between(start, end).toMillis() + " ms");

4、AutoCloseable

在 JDK1.7 引入了一个新的接口AutoCloseable, 通常它的实现类配合try{}使用,可在 IO 流的使用上,可自行关闭流,不用再去手动关闭流,使用起来更简洁优雅。

1
2
3
4
5
6
try (BufferedReader reader= new BufferedReader(new InputStreamReader(new FileInputStream("/tmp")))) {
List<String> list = reader.lines().collect(Collectors.toList());
System.out.println(list);
} catch (IOException e) {
e.printStackTrace();
}

主要原因就是在try(){}执行完毕之后,会调用方法AutoCloseable.close方法;只要实现了AutoCloseable接口,都可使用try(){}语法。

接下来利用这一特性,实现代码执行耗时的计算。

创建Cost类实现AutoCloseable:

1
2
3
4
5
6
7
8
9
10
public class Cost implements AutoCloseable {
private long start;
public Cost() {
start = System.currentTimeMillis();
}
@Override
public void close() throws Exception {
System.out.println("cost time: " + (System.currentTimeMillis() - start) + " ms");
}
}

接下来写测试类:

1
2
3
4
5
6
7
try(Cost cost = new Cost()) {
// 模拟执行业务代码
TimeUnit.SECONDS.sleep(1);

} catch (Exception e) {
e.printStackTrace();
}

运行测试代码,会输出cost time.

5、总结

以上有5种方法可以统计代码执行耗时,如果需要统计项目中每个方法的执行耗时,spring aop方式应是首选,若只是 统计某个代码块的执行耗时。其他的几种方法都可以,每个方法都可以尝试在项目中使用,当然最优雅的当属AutoCloseable方式了。


统计java代码执行耗时的N种方案
https://river106.cn/posts/fa958383.html
作者
river106
发布于
2021年2月18日
许可协议