平时的开发中,偶尔会遇到统计代码执行耗时的情况,一般代码如下:
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方式了。