Apache Commons-lang3提供的StopWatch执行时间监视器,以及Spring提供的StopWatch分析

【效率提升】使用 StopWatch 统计代码中的耗时操作 在Java开发中,对于需要做性能优化的接口,可以通过StopWatch优雅的实现各个节点的耗时监控,根据获取到的监控数据再针对性的进行优化。方法的调用,相对于背景中的两个时间相减,语义会更加明确一点。如果想要计算两个阶段之间的耗时的话,可以写一个新的StopWatch来继承Apache的StopWatch,并拓展对应方法。,由于Sleep的精确性,可能会有几号秒的误差,但实际上,这个工具并没有这么打印,下面看一下运行结果。有了这个结果之后,就可以定位到相对比较耗时的代码的位置,做出针对性的优化。 阅读详情

前言
编码过程中我们经常会希望得到一段代码(一个方法)的执行时间,本文将介绍两种时间监视器(秒表)来让你优雅的、灵活的处理这个问题。

Java源生方式
这种方式最最简单,最好理解,当然也是最为常用:我们自己书写。
例如:我们如果要统计一段代码的执行时间,经常会这么来写:

public static void main(String[] args) {
    long startTime = System.currentTimeMillis();   //获取开始时间

    //函数主体代码
    //...

    long endTime = System.currentTimeMillis(); //获取结束时间
    System.out.println("程序运行时间: " + (endTime - startTime) + "ms");
}

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

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

public static void main(String[] args) {
    Instant start = Instant.now();
    //doSomething();
    Instant end = Instant.now();

    Duration duration = Duration.between(start, end);
    System.out.println("millis = " + duration.toMillis());
}

这个比上面灵活度强一些。但也还是有一定的缺点:步骤稍显复杂,总体上还是不够优雅,也不是那么的灵活。
那么本文针对此问题介绍一个工具:StopWatch执行时间监视器。借助它来统计我们程序的执行时间,带给非常多的方便和优雅。

StopWatch需要依赖额外的Jar:commons-lang3或者spring-core,但因这两个Jar是Java开发中都必导的,因此依赖兼容性方面可以忽略

StopWatch有很多开源的框架都有提供类似的功能:比如Apache的commons-lang3,当然还有Spring framwork自己提供的,本文将针对此俩分别做介绍~

Commons-lang3的StopWatch
Apache提供的这个任务执行监视器功能丰富强大(比Spring的强大),灵活性强,如下经典实用案例:

public static void main(String[] args) throws Exception {
    StopWatch watch = StopWatch.createStarted(); //创建后立即start,常用
    //StopWatch watch = new StopWatch();
    //watch.start();

    Thread.sleep(1000);
    System.out.println("统计从开始到现在运行时间:" + watch.getTime() + "ms"); //1000ms

    Thread.sleep(1000);
    watch.split();
    System.out.println("从start到此刻为止的时间:" + watch.getTime());
    System.out.println("从开始到第一个切入点运行时间:" + watch.getSplitTime()); //2245

    Thread.sleep(1000);
    watch.split();
    System.out.println("从开始到第二个切入点运行时间:" + watch.getSplitTime());

    watch.reset(); //重置后必须使用start方法
    watch.start();
    Thread.sleep(1000);
    System.out.println("重新开始后到当前运行时间是:" + watch.getTime()); //1000

    watch.suspend(); //暂停
    Thread.sleep(6000); //模拟暂停6秒钟

    watch.resume(); //上面suspend,这里要想重新统计,需要恢复一下
    System.out.println("恢复后执行的时间是:" + watch.getTime()); //1000  注意此时这个值还是1000

    watch.stop();
    System.out.println("花费的时间》》" + watch.getTime() + "ms"); //1002ms
    System.out.println("花费的时间》》" + watch.getTime(TimeUnit.SECONDS) + "s"); //1s 可以直接转成s

}

打印结果:

统计从开始到现在运行时间:1007ms
从start到此刻为止的时间:2008
从开始到第一个切入点运行时间:2008
从开始到第二个切入点运行时间:3009
重新开始后到当前运行时间是:1000
恢复后执行的时间是:1000
花费的时间》》1001ms
花费的时间》》1s

如上就是StopWatch的基本使用方法,足以见到了它的强大吧,当然使用起来复杂度也是提升了些的。

核心原理解释
原理相对简单,简单看看源码便知:

// @since 2.0
public class StopWatch {
	// @since 3.5  这个静态方法出现得稍微晚点哦~
    public static StopWatch createStarted() {
        final StopWatch sw = new StopWatch();
        sw.start();
        return sw;
    }

	// 这些成员变量是实现的核心~~~~~~~~~~~~~~
    private State runningState = State.UNSTARTED;
    private SplitState splitState = SplitState.UNSPLIT;
    private long startTime;
	// 思考:为何有了nonaTime这里还得记录一个Millis Time呢???
	// 因为nanoTime只能拿来计算差值(耗时) 但是getStartTime()这个老API还得靠MillsTime~~~
    private long startTimeMillis;
    private long stopTime;
    
    // 可见:start方法可不是能够多次调用的哦~~和状态是有关的
    public void start() {
        if (this.runningState == State.STOPPED) {
            throw new IllegalStateException("Stopwatch must be reset before being restarted. ");
        }
        if (this.runningState != State.UNSTARTED) {
            throw new IllegalStateException("Stopwatch already started. ");
        }
        this.startTime = System.nanoTime();
        this.startTimeMillis = System.currentTimeMillis();
        this.runningState = State.RUNNING;
    }

	// 停表时,最重要的是记录下了stopTime 的值~~~然后标记状态
    public void stop() {
        if (this.runningState != State.RUNNING && this.runningState != State.SUSPENDED) {
            throw new IllegalStateException("Stopwatch is not running. ");
        }
        if (this.runningState == State.RUNNING) {
            this.stopTime = System.nanoTime();
        }
        this.runningState = State.STOPPED;
    }

	// 状态变为非开始状态...
    public void reset() {
        this.runningState = State.UNSTARTED;
        this.splitState = SplitState.UNSPLIT;
    }

	// 暂停:stopTime 也给了一个值
    public void suspend() {
        if (this.runningState != State.RUNNING) {
            throw new IllegalStateException("Stopwatch must be running to suspend. ");
        }
        this.stopTime = System.nanoTime();
        this.runningState = State.SUSPENDED;
    }

	// 这两个方法是获取差值的
    public long getTime() {
        return getNanoTime() / NANO_2_MILLIS;
    }
    // @since 3.5
    public long getTime(final TimeUnit timeUnit) {
        return timeUnit.convert(getNanoTime(), TimeUnit.NANOSECONDS);
    }

	// @since 2.4 老API  这叫获取启动的时间(啥时候启动的)
    public long getStartTime() {
        if (this.runningState == State.UNSTARTED) {
            throw new IllegalStateException("Stopwatch has not been started");
        }
        // System.nanoTime is for elapsed time
        return this.startTimeMillis;
    }
}

可以看到原理是很简单的,无非就是包装了暂停、回复、split等功能嘛

使用细节
getTime和getSplitTime有啥区别呢?
为了说明问题,此处我们看看getNanoTime()和getSplitNanoTime()亦可:

public long getNanoTime() {
    if (this.runningState == State.STOPPED || this.runningState == State.SUSPENDED) {
        return this.stopTime - this.startTime;
    } else if (this.runningState == State.UNSTARTED) {
        return 0;
    } else if (this.runningState == State.RUNNING) {
        return System.nanoTime() - this.startTime;
    }
    throw new RuntimeException("Illegal running state has occurred.");
}

public long getSplitNanoTime() {
    if (this.splitState != SplitState.SPLIT) {
        throw new IllegalStateException("Stopwatch must be split to get the split time. ");
    }
    return this.stopTime - this.startTime;
}

我们发现:

调用getSplit…相关方法前,必须先调用Split方法
spilit()方法源码如下:

public void split() {
    if (this.runningState != State.RUNNING) {
        throw new IllegalStateException("Stopwatch is not running. ");
    }
    this.stopTime = System.nanoTime();
    this.splitState = SplitState.SPLIT;
}

在调用split方法后,watch的状态改为了SPLIT。且,且,且stopTime 设置为了当前时间。因此此处我们的stopTime停止了,这个时候调用getSplitNanoTime(),返回的是start到split那时的时间差值。因此用此方法可以插入先停止stopTime()(有点插队的赶脚),最后再输出(先插好队,最后在输出)~

而getTime()就是拿当前的时间戳,减去startTime,一般不涉及到stopTime的值,因此splitTime处理计算时间显然更加的灵活,但是,一般我们使用getTime()就足够了

Spring的StopWatch
Spring提供的这个任务监视器,我还是蛮喜欢使用的,因为一个它能够帮我同事监控多个任务,使用起来也很方便。先看一个简单的使用案例:

注意:一个监视器能够记录多个任务的执行时间这个特点非常重要哦~
比如:我们可以记录多段代码耗时时间,然后一次性打印~

public static void main(String[] args) throws Exception {
    // 强烈每一个秒表都给一个id,这样查看日志起来能够更加的精确
    // 至于Id 我觉得给UUID是可行的~
    StopWatch sw = new StopWatch(UUID.randomUUID().toString());

    sw.start("起床");
    Thread.sleep(1000);
    System.out.println("当前任务名称:" + sw.currentTaskName());
    sw.stop();

    sw.start("洗漱");
    Thread.sleep(2000);
    System.out.println("当前任务名称:" + sw.currentTaskName());
    sw.stop();

    sw.start("锁门");
    Thread.sleep(500);
    System.out.println("当前任务名称:" + sw.currentTaskName());
    sw.stop();

    System.out.println(sw.prettyPrint()); // 这个方法打印在我们记录日志时是非常友好的  还有百分比的分析哦
    System.out.println(sw.shortSummary());
    System.out.println(sw.currentTaskName()); // stop后它的值为null


    // 最后一个任务的相关信息
    System.out.println(sw.getLastTaskName());
    System.out.println(sw.getLastTaskInfo());

    // 任务总的耗时  如果你想获取到每个任务详情(包括它的任务名、耗时等等)可使用
    System.out.println("所有任务总耗时:" + sw.getTotalTimeMillis());
    System.out.println("任务总数:" + sw.getTaskCount());
    System.out.println("所有任务详情:" + sw.getTaskInfo()); // 拿到所有的任务
}

打印:

当前任务名称:起床
当前任务名称:洗漱
当前任务名称:锁门
StopWatch 'd6ba9412-d551-4ba7-8b0e-1b7ccb42855d': running time (millis) = 3504
-----------------------------------------
ms     %     Task name
-----------------------------------------
01001  029%  起床
02000  057%  洗漱
00503  014%  锁门

StopWatch 'd6ba9412-d551-4ba7-8b0e-1b7ccb42855d': running time (millis) = 3504
null
锁门
org.springframework.util.StopWatch$TaskInfo@2d554825
所有任务总耗时:3504
任务总数:3
所有任务详情:[Lorg.springframework.util.StopWatch$TaskInfo;@68837a77

我个人偏爱使用Spring提供的这个监视器,是因为它提供的prettyPrint()打印在日志里进行分析可以非常的直观,并且我觉得提供的多任务支持也更加实用一点,当然仅仅个人偏好而已~

最后
很多时候,写代码也是一种艺术,而借助这种实用工具我就觉得艺术感更强些。希望我们能有追求更加美好事物的心,这点对于接纳新知识特别重要。此处推荐这个监视器来代替之前的的使用,能让小伙伴们更加灵活的分析你的代码~

转载自:https://blog.youkuaiyun.com/f641385712/article/details/82591603

告别点不亮!STM32F103驱动HT1621段码屏的常见坑点与调试心得 本文详细解析了STM32F103驱动HT1621段码屏的五大常见问题及解决方案,包括硬件连接、时序控制、RAM地址映射等关键难点。通过实测数据和代码示例,帮助开发者快速排查显示异常问题,提升驱动开发效率。特别针对HT1621与STM32F103的兼容性问题提供了专业调试建议。 阅读详情

相关推荐

放弃FFT全频计算!在STM32F407上用DFT单点计算提速50%的优化技巧

本文详细介绍了在STM32F407上通过DFT单点计算实现比FFT快50%的优化技巧,特别适用于生物阻抗分析、振动监测等只需关注单一频点的嵌入式场景。通过预计算相位角、查表法和混合精度计算等策略,显著提升计算效率和内存利用率,同时保持高精度。

weixin_28738397的博客 195

Java源生方式

这种方式最最简单,最好理解,当然也是最为常用:我们自己书写。 例如:我们如果要统计一段代码的执行时间,经常会这么来写: public static void main(String[] args) { long startTime = System.currentTimeMillis(); //获取开始时间 //函数主体代码 //... long endTi...

weixin_45121123的博客 346

记录LeNet的硬件加速器设计(一)

LeNet的硬件加速器设计实现。

2301_81029398的博客 3545

项目监控代码段耗时工具类apache commons lang3下的StopWatch用法

导入依赖 <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.4</version> </dependency> 常用方法介绍 start(); //开始计时 split(); //设置spli.

Seven71111的博客 1372

NUS-WIDE-10K数据集制作

NUS-WIDE是一个多标签数据集,数据集中一共包含26,9648个样本,可以分为81个类。最近在做跨模态检索项目,发现有很多论文里面都用到了NUS-WIDE-10K数据集,但是在网上也没有搜索到相关的数据集下载链接或者是数据集制作代码,所以自己动手写了一个NUS-WIDE-10K数据集的制作代码。 1.介绍 我在网上找到的最早关于NUS-WIDE-10K数据集描述的论文是:Cross-modal Retrieval with Correspondence Autoencoder。描述如下:作者选择了N

weixin_44012382的博客 4201

linux操作系统使用以太网连接ubuntu,设置固定ipv4

首先,您需要确定要配置的网络接口。可以使用ifconfig -a或ip addr命令来列出当前系统上的所有网络接口及其相关信息。找到您要配置的网络接口名称,例如eth0、ens33或enp0s3;保存并关闭文件后,您需要重启网络服务以使更改生效。在linux操作系统中,要使用交换机连接以太网可以直接使用交互界面;如果你的操作系统没有交互界面,你可以使用命令方式配置;点击ipv4,方式为手动,可以设置ip和子网了;开头,后接网络接口名称。第三步:点击有线最右边圆形控件;第二步:点击有线设置;

2301_79311842的博客 2406

StopWatch 简单使用

StopWath是apache commons lang3包下的一个任务执行时间监视器 主要方法: start(); //开始计时 split(); //设置split点 getSplitTime(); //获取从start 到 最后一次split的时间 reset(); //重置计时 suspend(); //暂停计时, 直到调用resume()后才恢复计时

Curtain 9008

2021年秋招面经分享·字节跳动【芯片工程师-系统架构】

前言 如果想参考本人背景情况的可见这篇概述 ============================ 正文开始 ============================== 【时间线】 7.29 字节一面 8.4 字节二面 8.11 字节三面 PS:红字表示我当时没答出来的问题,蓝字表示面试官的解答。 面经分享 一面·技术面【1小时5分钟】   面试官京腔重,聊high了所以没时间撕代码了,但是华为应该不会这样。 自我介绍; 介绍一下APB; APB中3个状态的跳转是怎么跳转的; AXI中va

qq_43132308的博客 5616

StopWatch使用

调用stop()方法时,必须是running时才可以调用,否则会报状态不合法错误。

301

别再折腾环境了!Windows 11 + VSCode + CMake 3.31.4 + MinGW-w64 一键式配置指南(附常见报错解决)

本文提供Windows 11下VSCode、CMake 3.31.4和MinGW-w64的一键式配置指南,帮助开发者快速搭建高效C++开发环境。涵盖工具链选型、环境变量配置、项目初始化及常见报错解决方案,大幅提升开发效率。

weixin_28841265的博客 187

利用AI辅助工具Codex在30分钟内高效生成发明专利说明书草案

Codex 是什么?简单说,它是 OpenAI 推出的一个高级 AI 工作平台,最初定位是软件开发辅助工具,但现在它的能力边界已经远远超出了写代码。根据 OpenAI 官方信息,每周有超过 500 万人使用 Codex,其中 40% 的新用户是非开发者,包括分析师、营销人员、研究人员等。这意味着 Codex 正在从一个程序员专属工具,演变为一个面向广泛知识工作者的生产力中枢。 那么,它和我们今天要谈的“写发明专利”有什么关系?核心在于 Codex 的“角色专属插件”和“上下文构建”能力。它不再只是根据零散的

weixin_29053067的博客 321

【小家java】Apache Commons-lang3提供的StopWatch执行时间监视器,以及Spring提供的StopWatch分析

前言 我们如果要统计一段代码的执行时间:我们的办法是 public static void main(String[] args) { long startTime=System.currentTimeMillis(); //获取开始时间 //函数主体代码 //... long endTime=System.curre...

架构师:通透,才能写出好代码! 6078

43、基于机器学习的GNSS信号质量监测方法

本文提出了一种基于支持向量机(SVM)的GNSS信号质量监测方法,旨在有效检测邪恶波形(EWF)威胁并抑制多径干扰对导航精度的影响。通过构建包含现场采集与合成数据的数据集,结合11个相关器测量值、链路预算、仰角和方位角等特征,采用RBF核函数的SVM模型进行分类。研究评估了不同平滑时间窗口对漏检率和误报率的影响,结果表明在约35-40秒平滑时间下性能趋于稳定,并可通过多数投票机制进一步优化检测性能。该方案适用于星载GNSS接收器,在计算资源受限条件下实现了高可靠性与低完整性风险的平衡。

yyy34的博客 191

Apache Commons-lang3提供的StopWatch执行时间监视器,以及Spring提供的StopWatch分析[转]

https://blog.youkuaiyun.com/f641385712/article/details/82591603?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase

Beat_IT的博客 311

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Java 统计运行时间之 Apache Commons-lang3和Spring Core提供的StopWatch分析

前言 编码过程中我们经常会希望得到一段代码(一个方法)的执行时间,本文将介绍两种时间监视器(秒表)来让你优雅的、灵活的处理这个问题。 Java源生方式 这种方式最最简单,最好理解,当然也是最为常用:我们自己书写。 例如:我们如果要统计一段代码的执行时间,经常会这么来写: public static void main(String[] args) { long startTime = System.currentTimeMillis(); //获取开始时间 ...

luckykapok918的专栏 1304

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Apache和Spring提供的StopWatch执行时间监视器

相关阅读 【小家java】java5新特性(简述十大新特性) 重要一跃 【小家java】java6新特性(简述十大新特性) 鸡肋升级 【小家java】java7新特性(简述八大新特性) 不温不火 【小家java】java8新特性(简述十大新特性) 饱受赞誉 【小家java】java9新特性(简述十大新特性) 褒贬不一 【小家java】java10新特性(简述十大新特性) 小步迭代 【小家...

weixin_30800807的博客 176

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

StopWatch任务执行时间监控

在最近代码codereview中,发现代码中大量使用了StopWatch 这个类去监视执行的时间。这里总结一下大概的介绍。StopWatch 在spring中和apache中均提供了类似的功能,这里分别介绍一下。 一、Apache下的StopWatch       StopWath是apache commons lang包下的一个任务执行时间监视器,具体位置是org.apache.co

tanyunlong_nice的专栏 2519

JAVA常用计时器StopWatch的使用(监控Java代码运行时间和分析性能,侧重于开发或调试时使用)

目录 引子 Stopwatch简介和它常用的两种工具包 编写时所引用和借鉴的url 引子 最初我们对一个方法的运行时间监控采用的可能是: long startTime=System.currentTimeMillis(); //获取开始时间 //业务逻辑...... long endTime=System.currentTimeMillis(); //获取结束时间 System.out.println("程序运行时间: "+(endTime-startTime)+"ms"); ...

huqiwuhuiju的博客 2356

10-错误-java.lang.IllegalStateException Stopwatch is not running

10-错误-java.lang.IllegalStateException Stopwatch is not running

weixin_43873121的博客 1060

Spring计时器StopWatch使用详解 源码分析

前言     在我们日常开发中有时需要对某一个运算或者方法进行计时,以便我们来观察该运算或方法是否符合我们的预期。     在Spring中,为了统计任务的执行时间,开发了一个轻量级的计时器,它就是:StopWatch。StopWatch是一个轻量级的秒表,允许多个任务的计时,暴露每个命名任务的总运行时间和运行时间。隐藏使用System.currentTimeMillis(),提高应用程序代码的可读性并减少计算错误的可能性。 请

秦延金 1379

spring-framework的StopWatch类详解,每个方法带有具体的例子

org.apache.commons.lang3.time.StopWatch 是 Apache Commons Lang 库中的一个工具类,用于测量代码执行时间。这个类提供了一系列便捷的方法,可以帮助我们轻松地对 Java 代码中的耗时操作进行计时。

jiayoudangdang的博客 5534

StopWath,apache commons lang3 包下的一个任务执行时间监视器的使用

【代码】StopWath,apache commons lang3 包下的一个任务执行时间监视器的使用。

qq_36608622的博客 819

java stopwatch_Java中的秒表-StopWatch

业务代码或者算法的性能一直是我们重要的关注点之一。而衡量性能的重要指标之一就是时间复杂度。我们除了用大O表示法外,有时还需要直观地通过程序的实际运行时间衡量算法的性能。今天我们就介绍一下在计时方面十分重要的工具类StopWatch。StopWatch是不在java标准包中的,你可以在以下两个程序包中找到StopWatch工具类org.apache.commons.lang3.timeApache ...

weixin_35762250的博客 1554

StopWatch 测量代码执行时间

StopWatch类在包中。它能够精确地测量代码执行时间,并提供了一些便捷的功能来记录和格式化时间信息。

weixin_51506966的博客 925

java中时间监视器,Commons-lang3提供的StopWatch执行时间监视器

Commons-lang3提供的StopWatch执行时间监视器, spring也提供了同样功能的工具前言我们如果要统计一段代码的执行时间:我们的办法是public static void main(String[] args) {long startTime=System.currentTimeMillis(); //获取开始时间//函数主体代码//...long endTime=Syste...

weixin_36111764的博客 961

C# Stopwatch类_性能_时间计时器

在研究性能的时候,完全可以使用Stopwatch计时器计算一项技术的效率。但是有时想知道某想技术的性能的时候,又常常想不起可以运用Stopwatch这个东西,太可悲了。 属性:   Elapsed       获取当前实例测量得出的总运行时间。   ElapsedMilliseconds 获取当前实例测量得出的总运行时间(以毫秒为单位)。   ElapsedTicks ...

suxuelian的博客 1653
上一篇: java设计模式-原型模式
下一篇: java中文排序
code1Boy
博客等级 码龄10年 45粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值