前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >分享一个统计代码块耗时的小工具

分享一个统计代码块耗时的小工具

作者头像
微观技术
发布2021-03-11 14:11:24
3910
发布2021-03-11 14:11:24
举报
文章被收录于专栏:微观技术

相信很多人都遇到这样一个问题?

加班加点,上线了一个功能,但接口的响应时间有点长?

如何定位排查?

普通研发人员一般会采用下面方式,在很多位置点埋入开始时间戳、结束时间戳,相减便得到耗时。代码如下:

代码语言:javascript
复制
long start1 = System.currentTimeMillis();
// 模拟业务逻辑处理
Thread.sleep(300);
long end1 = System.currentTimeMillis();

long start2 = System.currentTimeMillis();
// 模拟业务逻辑处理
Thread.sleep(730);
long end2 = System.currentTimeMillis();

System.out.println("执行操作1,耗时:" + (end1 - start1));
System.out.println("执行操作2,耗时:" + (end2 - start2));

虽然书写简单,但导致系统中充斥着大量低级代码,比较烦人,很容易让人怀疑你的技术实力。

我们的直接想法是能不能写个工具类,即统计代码块耗时,还能将分析结果直观展示出来

恰好 Spring框架提供了一个工具类,org.springframework.util.StopWatch,提供了轻量级统计功能,对应的pom文件依赖

代码语言:javascript
复制
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>5.2.9.RELEASE</version>
</dependency>

StopWatch 源码

代码语言:javascript
复制
省略。。。
public void start(String taskName) throws IllegalStateException {
    if (this.currentTaskName != null) {
        throw new IllegalStateException("Can't start StopWatch: it's already running");
    } else {
        this.currentTaskName = taskName;
        this.startTimeNanos = System.nanoTime();
    }
}

public void stop() throws IllegalStateException {
    if (this.currentTaskName == null) {
        throw new IllegalStateException("Can't stop StopWatch: it's not running");
    } else {
        long lastTime = System.nanoTime() - this.startTimeNanos;
        this.totalTimeNanos += lastTime;
        this.lastTaskInfo = new StopWatch.TaskInfo(this.currentTaskName, lastTime);
        if (this.keepTaskList) {
            this.taskList.add(this.lastTaskInfo);
        }

        ++this.taskCount;
        this.currentTaskName = null;
    }
}

省略。。。

start与stop方法分别记录开始时间与结束时间。

其中在记录结束时间时,会维护一个链表类型的tasklist属性,从而使该类可记录多个任务,最后的输出也仅仅是对之前记录的信息做了一个统一的归纳输出,从而使结果更加直观的展示出来。

prettyPrint方法,可直观的输出代码执行耗时,以及执行时间百分比。

StopWatch 优点

  • Spring框架自带,操作简单,开箱即用
  • 任务start时可以指定name,显示更加友好
  • 数据归纳,展示每项任务耗时与占用总时间的百分比,展示结果直观

缺点:

  • 一个StopWatch不能同时启动多个任务,必须在当前任务stop之后才能开启新的task。若要一次开启多个,需要new一个新的StopWatch实例
  • 代码有侵入性

代码示例:

代码语言:javascript
复制
StopWatch sw = new StopWatch();
sw.start("任务1");
// 模拟业务逻辑处理
Thread.sleep(300);
sw.stop();

sw.start("任务2");
// 模拟业务逻辑处理
Thread.sleep(730);
sw.stop();

System.out.println(sw.prettyPrint());

运行结果:

代码语言:javascript
复制
StopWatch '': running time (millis) = 1033
-----------------------------------------
ms     %     Task name
-----------------------------------------
00303  029%  任务1
00730  071%  任务2

类似工具

除了上面 Spring 提供了工具外,apache下的org.apache.commons.lang.time.StopWatch 和 Guava 下的com.google.common.base.Stopwatch 都提供了类似的工具

大家根据自己的喜好,选择使用。原理大同小异,只是编码风格略有不同。

项目源码地址

代码语言:javascript
复制
https://github.com/aalansehaiyang/spring-boot-bulking  

模块:spring-boot-bulking-tool

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-03-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微观技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 类似工具
  • 项目源码地址
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档