优化开发效率:耗时分析利器Apache StopWatch

简介: Apache StopWatch是Apache Commons库中的一个组件,它提供了简单而强大的计时器功能。StopWatch可以帮助开发人员精确地计时方法或代码块的执行时间,以便进行性能分析和优化。它提供了计时、暂停、继续、重置等功能,使我们能够更好地监控和控制代码的执行时间。

Apache StopWatch是Apache Commons库中的一个组件,它提供了简单而强大的计时器功能。StopWatch可以帮助开发人员精确地计时方法或代码块的执行时间,以便进行性能分析和优化。它提供了计时、暂停、继续、重置等功能,使我们能够更好地监控和控制代码的执行时间。

在这给家人们准备了一些java书籍
在这里插入图片描述

请关注微信公众号 修己xj发送601获取阿里云盘分享链接

与System.currentTimeMillis()打印耗时相比

  • 精确性:StopWatch提供了更高的精确性。当前毫秒数的差是一种简单粗略的计时方式,但它无法提供毫秒级别以下的时间精度。而StopWatch使用更精确的计时机制,可以测量和记录更细小的时间间隔,提供更准确的耗时信息。

  • 可读性:StopWatch提供了更友好的耗时信息。当前毫秒数的差通常以数字形式呈现,难以直观地理解。而StopWatch可以提供更加可读的耗时信息,包括毫秒、秒、分钟等单位,并可以格式化输出,方便开发人员理解和分析。

  • 多段计时:StopWatch支持多段计时。使用当前毫秒数的差只能获取整体耗时,无法区分不同阶段的执行时间。而StopWatch提供了分段计时的功能,可以记录不同阶段的耗时,帮助开发人员更细致地分析任务或方法的执行性能。

  • 功能丰富:StopWatch提供了更多功能和控制选项。除了计时和打印耗时外,StopWatch还支持计时器的暂停、继续、重置等操作。这使得开发人员可以更灵活地控制计时过程,并在需要时进行更精细的时间管理。

Spring Boot与Apache StopWatch的结合应

功能
  • 性能分析:借助Apache StopWatch,我们可以在Spring Boot应用程序中测量和监控关键代码块的执行时间。通过计时器的记录和统计,我们能够发现潜在的性能瓶颈,并针对性地进行优化,提升系统的响应速度和并发处理能力。

  • 接口性能监控:在开发和测试阶段,我们可以使用Apache StopWatch来监控接口的响应时间。通过在接口方法中嵌入计时器,我们可以实时地测量每个接口的执行时间,并记录下来。这有助于我们发现耗时较长的接口,并进行性能调优。

  • 任务调度监控:Spring Boot提供了强大的任务调度功能,可以进行定时任务的管理和执行。结合Apache StopWatch,我们可以在任务方法中嵌入计时器,测量任务的执行时间,并对任务的性能进行监控和优化。

  • 日志记录:使用Apache StopWatch可以在日志中记录关键代码块的执行时间。这对于排查系统问题、定位性能瓶颈非常有帮助。通过将计时器的记录输出到日志中,我们可以在开发和生产环境中追踪和分析代码的执行时间。

依赖
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.12.0</version>
    </dependency>
方法说明
  • start():启动计时器。在需要开始计时的地方调用此方法,例如在某个任务或方法的起始位置。

  • stop():停止计时器。在需要结束计时的地方调用此方法,例如在某个任务或方法的结束位置。

  • reset():重置计时器。将计时器的时间重置为0,可以在需要重新计时的地方调用此方法。

  • split():记录分段时间。在某个任务或方法的不同阶段调用此方法,可以记录各个阶段的执行时间。

  • unsplit():取消最后一次分段时间。如果在某个阶段调用了split()方法,但后续发现该阶段不需要计算执行时间,可以调用此方法进行取消。

  • suspend():暂停计时器。可以在需要暂停计时的地方调用此方法,例如在处理某个中断或等待的过程中。

  • resume():恢复计时器。在暂停后需要继续计时的地方调用此方法,使计时器继续计算时间。

  • getTime():获取经过的总时间(以毫秒为单位)。表示从开始计时到调用getTime()方法时经过的时间。

示例代码
  • 打印耗时:
package cn.xj.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.StopWatch;

import java.util.concurrent.TimeUnit;

@Slf4j
public class Test {
   
   
    public static void main(String[] args) throws InterruptedException {
   
   
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        Thread.sleep(3000);
        stopWatch.stop();
        log.info("方法执行时间:{}毫秒",stopWatch.getTime());
        log.info("方法执行时间:{}秒",stopWatch.getTime(TimeUnit.SECONDS));
    }
}

输出

已连接到目标 VM, 地址: ''127.0.0.1:52888',传输: '套接字''
21:03:47.430 [main] INFO cn.xj.common.utils.Test - 方法执行时间:3011毫秒
21:03:47.433 [main] INFO cn.xj.common.utils.Test - 方法执行时间:3秒
与目标 VM 断开连接, 地址为: ''127.0.0.1:52888',传输: '套接字''

进程已结束,退出代码0
  • 暂停和恢复计时器:
package cn.xj.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.StopWatch;

import java.util.concurrent.TimeUnit;

@Slf4j
public class Test {
   
   
    public static void main(String[] args) throws InterruptedException {
   
   
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();

        // 执行业务逻辑,一顿执行猛如虎,一看代码睡3秒
        Thread.sleep(3000);

        stopWatch.suspend(); // 暂停计时器

        // 执行其他操作,暂停期间不计入计时
        Thread.sleep(2000);

        stopWatch.resume(); // 恢复计时器

        // 继续执行操作,让我再睡1秒
        Thread.sleep(1000);

        stopWatch.stop();
        log.info("方法执行时间:{}毫秒",stopWatch.getTime());
        log.info("方法执行时间:{}秒",stopWatch.getTime(TimeUnit.SECONDS));
    }
}

输出

已连接到目标 VM, 地址: ''127.0.0.1:53100',传输: '套接字''
21:15:38.963 [main] INFO cn.xj.common.utils.Test - 方法执行时间:4017毫秒
21:15:38.967 [main] INFO cn.xj.common.utils.Test - 方法执行时间:4秒
与目标 VM 断开连接, 地址为: ''127.0.0.1:53100',传输: '套接字''

进程已结束,退出代码0
  • 记录多个分段时间:
package cn.xj.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.StopWatch;

@Slf4j
public class Test {
   
   
    public static void main(String[] args) throws InterruptedException {
   
   
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();

        // 第一段业务逻辑,一顿执行猛如虎,一看代码睡3秒
        Thread.sleep(3000);

        stopWatch.split();
        log.info("第一段耗时:{}毫秒",stopWatch.getSplitTime());

        // 第二段业务逻辑,再睡2秒
        Thread.sleep(2000);
        stopWatch.split();
        log.info("第二段耗时:{}毫秒",stopWatch.getSplitTime());

        // 第三段业务逻辑,这次睡4秒
        Thread.sleep(4000);
        stopWatch.stop();

        log.info("总耗时:{}毫秒",stopWatch.getTime());
    }
}

输出

已连接到目标 VM, 地址: ''127.0.0.1:58391',传输: '套接字''
21:37:15.972 [main] INFO cn.xj.common.utils.Test - 第一段耗时:3014毫秒
21:37:17.988 [main] INFO cn.xj.common.utils.Test - 第二段耗时:5031毫秒
21:37:22.002 [main] INFO cn.xj.common.utils.Test - 总耗时:9046毫秒
与目标 VM 断开连接, 地址为: ''127.0.0.1:58391',传输: '套接字''

进程已结束,退出代码0
  • 重置计时器:
package cn.xj.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.StopWatch;

import java.util.concurrent.TimeUnit;

@Slf4j
public class Test {
   
   
    public static void main(String[] args) throws InterruptedException {
   
   
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();

        // 执行业务逻辑1,一顿执行猛如虎,一看代码睡3秒
        Thread.sleep(3000);
        stopWatch.stop();

        log.info("方法1执行时间:{}毫秒",stopWatch.getTime());
        log.info("方法1执行时间:{}秒",stopWatch.getTime(TimeUnit.SECONDS));

        stopWatch.reset(); // 重置计时器

        stopWatch.start();

        // 执行其他业务逻辑2,扶我躺下,我还能睡2秒
        Thread.sleep(2000);

        stopWatch.stop();

        log.info("方法2执行时间:{}毫秒",stopWatch.getTime());
        log.info("方法2执行时间:{}秒",stopWatch.getTime(TimeUnit.SECONDS));
    }
}

输出

已连接到目标 VM, 地址: ''127.0.0.1:58622',传输: '套接字''
21:48:25.252 [main] INFO cn.xj.common.utils.Test - 方法1执行时间:3005毫秒
21:48:25.255 [main] INFO cn.xj.common.utils.Test - 方法1执行时间:3秒
21:48:27.263 [main] INFO cn.xj.common.utils.Test - 方法2执行时间:2007毫秒
21:48:27.263 [main] INFO cn.xj.common.utils.Test - 方法2执行时间:2秒
与目标 VM 断开连接, 地址为: ''127.0.0.1:58622',传输: '套接字''

进程已结束,退出代码0
目录
相关文章
|
9月前
|
存储 自然语言处理 分布式计算
Apache Doris 3.1 正式发布:半结构化分析全面升级,湖仓一体能力再跃新高
Apache Doris 3.1 正式发布!全面升级半结构化分析,支持 VARIANT 稀疏列与模板化 Schema,提升湖仓一体能力,增强 Iceberg/Paimon 集成,优化存储引擎与查询性能,助力高效数据分析。
1080 4
Apache Doris 3.1 正式发布:半结构化分析全面升级,湖仓一体能力再跃新高
|
消息中间件 数据挖掘 Kafka
Apache Kafka流处理实战:构建实时数据分析应用
【10月更文挑战第24天】在当今这个数据爆炸的时代,能够快速准确地处理实时数据变得尤为重要。无论是金融交易监控、网络行为分析还是物联网设备的数据收集,实时数据处理技术都是不可或缺的一部分。Apache Kafka作为一款高性能的消息队列系统,不仅支持传统的消息传递模式,还提供了强大的流处理能力,能够帮助开发者构建高效、可扩展的实时数据分析应用。
1111 5
|
消息中间件 监控 大数据
优化Apache Kafka性能:最佳实践与调优策略
【10月更文挑战第24天】作为一名已经对Apache Kafka有所了解并有实际使用经验的开发者,我深知在大数据处理和实时数据流传输中,Kafka的重要性不言而喻。然而,在面对日益增长的数据量和业务需求时,如何保证系统的高性能和稳定性成为了摆在我们面前的一个挑战。本文将从我的个人视角出发,分享一些关于如何通过合理的配置和调优来提高Kafka性能的经验和建议。
640 4
|
存储 SQL Apache
为什么 Apache Doris 是比 Elasticsearch 更好的实时分析替代方案?
本文将从技术选型的视角,从开放性、系统架构、实时写入、实时存储、实时查询等多方面,深入分析 Apache Doris 与 Elasticsearch 的能力差异及性能表现
1762 17
为什么 Apache Doris 是比 Elasticsearch 更好的实时分析替代方案?
|
12月前
|
人工智能 运维 监控
Aipy实战:分析apache2日志中的网站攻击痕迹
Apache2日志系统灵活且信息全面,但安全分析、实时分析和合规性审计存在较高技术门槛。为降低难度,可借助AI工具如aipy高效分析日志,快速发现攻击痕迹并提供反制措施。通过结合AI与学习技术知识,新手运维人员能更轻松掌握复杂日志分析任务,提升工作效率与技能水平。
|
监控 安全 BI
优化 Apache 日志记录的 5 个最佳实践
Apache 日志记录对于维护系统运行状况和网络安全至关重要,其核心包括访问日志与错误日志的管理。通过制定合理的日志策略,如选择合适的日志格式、利用条件日志减少冗余、优化日志级别、使用取证模块提升安全性及实施日志轮换,可有效提高日志可用性并降低系统负担。此外,借助 Eventlog Analyzer 等专业工具,能够实现日志的高效收集、可视化分析与威胁检测,从而精准定位安全隐患、评估服务器性能,并满足合规需求,为强化网络安全提供有力支持。
334 0
优化 Apache 日志记录的 5 个最佳实践
|
存储 SQL Apache
Apache Doris 开源最顶级基于MPP架构的高性能实时分析数据库
Apache Doris 是一个基于 MPP 架构的高性能实时分析数据库,以其极高的速度和易用性著称。它支持高并发点查询和复杂分析场景,适用于报表分析、即席查询、数据仓库和数据湖查询加速等。最新发布的 2.0.2 版本在性能、稳定性和多租户支持方面有显著提升。社区活跃,已广泛应用于电商、广告、用户行为分析等领域。
Apache Doris 开源最顶级基于MPP架构的高性能实时分析数据库
|
监控 Cloud Native BI
8+ 典型分析场景,25+ 标杆案例,Apache Doris 和 SelectDB 精选案例集(2024版)电子版上线
飞轮科技正式推出 Apache Doris 和 SelectDB 精选案例集 ——《走向现代化的数据仓库(2024 版)》,汇聚了来自各行各业的成功案例与实践经验。该书以行业为划分标准,辅以使用场景标签,旨在为读者提供一个高度整合、全面涵盖、分类清晰且易于查阅的学习资源库。
641 8
|
存储 数据挖掘 数据处理
Apache Paimon 是一款高性能的数据湖框架,支持流式和批处理,适用于实时数据分析
【10月更文挑战第8天】随着数据湖技术的发展,越来越多企业开始利用这一技术优化数据处理。Apache Paimon 是一款高性能的数据湖框架,支持流式和批处理,适用于实时数据分析。本文分享了巴别时代在构建基于 Paimon 的 Streaming Lakehouse 的探索和实践经验,包括示例代码和实际应用中的优势与挑战。
909 1
|
存储 大数据 分布式数据库
大数据-165 Apache Kylin Cube优化 案例 2 定义衍生维度及对比 & 聚合组 & RowKeys
大数据-165 Apache Kylin Cube优化 案例 2 定义衍生维度及对比 & 聚合组 & RowKeys
317 1

热门文章

最新文章

推荐镜像

更多