java代码优化,需要获取关键行耗时?

最近想将一个业务方法优化一下,获取关键行的耗时(比如接口调用行,数据库请求行), 已知可以使用System.currentTimeMillis()来做…
关注者
18
被浏览
5,306

6 个回答


历史文章(文章累计450+) 国内最全的Spring Boot系列之一 》《 国内最全的Spring Boot系列之二 》《 国内最全的Spring Boot系列之三 》《 国内最全的Spring Boot系列之四 》《 国内最全的Spring Boot系列之 走进MyBatis源码一探Spring扩展点「知识点多多」「扩展点实战系列」- 第449篇

走进SpringBoot源码吃透Spring扩展点「扩展点实战系列」- 第450篇 5个月的精华:Spring/SpringBoot扩展点手册:手册在手,编码无忧:全网独一份 - 第451篇 SpringBoot添加外部jar包及打包(亲测有效) - 第452篇 SpringBoot引入外部jar包,项目打包成war包发布(亲测有效) - 第453篇

SpringBoot中使用Spring-Retry重试框架 - 第454篇


悟纤:最近代码逻辑,添加了很多的耗时的代码,感觉写的不是很好,师傅有更好的方案吗?

师傅:这个倒是有一个秒表StopWatch,可以稍微优化代码。

悟纤:那师傅介绍一下,让徒儿也增长下功力。



师傅:要不我直接把内里传给你吧。



悟纤:那最好不过了。

师傅:你想太多了。

悟纤:看来是电视看多了,这个时代,增加内力还得靠自己,木有办法,宝宝苦,宝宝累,宝宝好难受。



师傅:这个或许是你老了之后,你值得回忆的地方。

悟纤:那也是噢~




导读

如果想知道一个方法的执行耗时时长,一般的思路是:记录开始时间,执行业务代码,记录结束时间,方法的耗时就等于=结束时间-开始时间。这种方式可以实现基本的统计需求,如果要统计各个任务的占比,那么代码的复杂度就会增加,当然你封装出来一个类专门来处理执行耗时类。

如果使用了Spring框架,那么Spring已经提供了一个秒表工具StopWatch。

一、Java原生方式

这种方式最最简单,最好理解,经常会这么来写:

public void test1() throws InterruptedException {
    long startTime = System.currentTimeMillis();   //获取开始时间
    //函数主体代码
    //...
    TimeUnit.SECONDS.sleep(1);
    long endTime = System.currentTimeMillis(); //获取结束时间
    System.out.println("程序运行时间:" + (endTime - startTime) + "ms");
}


大多数时候我们使用ms来表示即可,但是这么写缺乏灵活性。倘若我们要展示成纳秒、秒、甚至分钟,还得我们自己处理(把毫秒值拿来进行转换~ )

当然可能到了JDK8以后,我们这么做能变得稍微灵活一些:可以这么处理:

public void test2() throws InterruptedException {
    Instant start = Instant.now();
    //doSomething();
    TimeUnit.SECONDS.sleep(1);
    Instant end = Instant.now();
    Duration duration = Duration.between(start, end);
    System.out.println("程序运行时间(毫秒) = " + duration.toMillis());
    System.out.println("程序运行时间(纳秒) = " + duration.toNanos());
}

这个比上面灵活度强一些,但还是有一定的缺点:步骤稍显复杂,总体上还是不够优雅,也不是那么的灵活,多个任务的时候编写不方便。

那么本文针对此问题介绍一个工具:StopWatch执行时间监视器。借助它来统计我们程序的执行时间,带给非常多的方便和优雅。

二、秒表StopWatch

工具类StopWatch,秒表工具,执行时间监视器,用来统计任务的耗时的工具类。

2.1 工具类提供者

不单单只有spring提供了这个工具类,apache,google也提供了:

com.google.common.base.Stopwatch;

org.apache.commons.lang3.time.StopWatch;

springframework.util.StopWatch;

2.2 工具类使用

对于Spring StopWatch的使用很简单,直接看下代码:

public void test3() throws InterruptedException {
    StopWatch stopWatch = new StopWatch("用户注册");
    //启动任务一
    stopWatch.start("保存用户信息");
    //执行业务逻辑
    TimeUnit.SECONDS.sleep(1);
    stopWatch.stop();
    //启动任务二
    stopWatch.start("创建用户钱包信息");
    //执行业务逻辑
    TimeUnit.SECONDS.sleep(2);
    stopWatch.stop();
    //会输出所有任务的信息
    System.out.println(stopWatch.prettyPrint());
    // 只输出总的:StopWatch '用户注册': running time = 3004621914 ns
    //System.out.println(stopWatch.shortSummary());