StopWatch的使用

StopWatch的使用

  • 【一】简介
    • 【1】不使用StopWatch的案例
    • 【2】使用StopWatch的案例
  • 【二】源码分析
    • 【1】查看源码
    • 【2】StopWatch优缺点:

【一】简介

stopWatch是org.springframework.util包下的一个工具类,使用它可直观的输出代码执行耗时,以及执行时间百分比

【1】不使用StopWatch的案例

在未使用这个工具类之前,如果我们需要统计某段代码的耗时,我们会这样写:

public static void main(String[] args) throws InterruptedException {test0();
}public static void test0() throws InterruptedException {long start = System.currentTimeMillis();// do somethingThread.sleep(100);long end = System.currentTimeMillis();long start2 = System.currentTimeMillis();// do somethingThread.sleep(200);long end2 = System.currentTimeMillis();System.out.println("某某1执行耗时:" + (end - start));System.out.println("某某2执行耗时:" + (end2 - start2));
}

执行结果如下:

某某1执行耗时:100
某某2执行耗时:200

【2】使用StopWatch的案例

public class StopWatchDemo {public static void main(String[] args) throws InterruptedException {test1();}public static void test1() throws InterruptedException {StopWatch sw = new StopWatch("test");sw.start("task1");// do somethingThread.sleep(100);sw.stop();sw.start("task2");// do somethingThread.sleep(200);sw.stop();System.out.println("sw.prettyPrint()~~~~~~~~~~~~~~~~~");System.out.println(sw.prettyPrint());}}

运行结果如下:

sw.prettyPrint()~~~~~~~~~~~~~~~~~
StopWatch 'test': running time (millis) = 310
-----------------------------------------
ms     %     Task name
-----------------------------------------
00110  035%  task1
00200  065%  task2

除此之外,还有以下两个方法shortSummary,getTotalTimeMillis,查看程序执行时间。

System.out.println("sw.shortSummary()~~~~~~~~~~~~~~~~~");
System.out.println(sw.shortSummary());
System.out.println("sw.getTotalTimeMillis()~~~~~~~~~~~~~~~~~");
System.out.println(sw.getTotalTimeMillis());
运行结果
sw.shortSummary()~~~~~~~~~~~~~~~~~
StopWatch 'test': running time (millis) = 308
sw.getTotalTimeMillis()~~~~~~~~~~~~~~~~~
308

【二】源码分析

【1】查看源码

其实以上内容在该工具类中实现也极其简单,通过start与stop方法分别记录开始时间与结束时间,其中在记录结束时间时,会维护一个链表类型的tasklist属性,从而使该类可记录多个任务,最后的输出也仅仅是对之前记录的信息做了一个统一的归纳输出,从而使结果更加直观的展示出来。
我们来看下源码:

import java.text.NumberFormat;
import java.util.LinkedList;
import java.util.List;public class StopWatch {private final String id;private boolean keepTaskList = true;private final List<TaskInfo> taskList = new LinkedList();private long startTimeMillis;private boolean running;private String currentTaskName;private StopWatch.TaskInfo lastTaskInfo;private int taskCount;private long totalTimeMillis;public StopWatch() {this.id = "";}public StopWatch(String id) {this.id = id;}public void setKeepTaskList(boolean keepTaskList) {this.keepTaskList = keepTaskList;}public void start() throws IllegalStateException {this.start("");}public void start(String taskName) throws IllegalStateException {if (this.running) {throw new IllegalStateException("Can't start StopWatch: it's already running");} else {this.startTimeMillis = System.currentTimeMillis();this.running = true;this.currentTaskName = taskName;}}public void stop() throws IllegalStateException {if (!this.running) {throw new IllegalStateException("Can't stop StopWatch: it's not running");} else {long lastTime = System.currentTimeMillis() - this.startTimeMillis;this.totalTimeMillis += lastTime;this.lastTaskInfo = new StopWatch.TaskInfo(this.currentTaskName, lastTime);if (this.keepTaskList) {this.taskList.add(this.lastTaskInfo);}++this.taskCount;this.running = false;this.currentTaskName = null;}}public boolean isRunning() {return this.running;}public long getLastTaskTimeMillis() throws IllegalStateException {if (this.lastTaskInfo == null) {throw new IllegalStateException("No tasks run: can't get last task interval");} else {return this.lastTaskInfo.getTimeMillis();}}public String getLastTaskName() throws IllegalStateException {if (this.lastTaskInfo == null) {throw new IllegalStateException("No tasks run: can't get last task name");} else {return this.lastTaskInfo.getTaskName();}}public StopWatch.TaskInfo getLastTaskInfo() throws IllegalStateException {if (this.lastTaskInfo == null) {throw new IllegalStateException("No tasks run: can't get last task info");} else {return this.lastTaskInfo;}}public long getTotalTimeMillis() {return this.totalTimeMillis;}public double getTotalTimeSeconds() {return (double) this.totalTimeMillis / 1000.0D;}public int getTaskCount() {return this.taskCount;}public StopWatch.TaskInfo[] getTaskInfo() {if (!this.keepTaskList) {throw new UnsupportedOperationException("Task info is not being kept!");} else {return (StopWatch.TaskInfo[]) this.taskList.toArray(new StopWatch.TaskInfo[this.taskList.size()]);}}public String shortSummary() {return "StopWatch '" + this.id + "': running time (millis) = " + this.getTotalTimeMillis();}public String prettyPrint() {StringBuilder sb = new StringBuilder(this.shortSummary());sb.append('\n');if (!this.keepTaskList) {sb.append("No task info kept");} else {sb.append("-----------------------------------------\n");sb.append("ms     %     Task name\n");sb.append("-----------------------------------------\n");NumberFormat nf = NumberFormat.getNumberInstance();nf.setMinimumIntegerDigits(5);nf.setGroupingUsed(false);NumberFormat pf = NumberFormat.getPercentInstance();pf.setMinimumIntegerDigits(3);pf.setGroupingUsed(false);StopWatch.TaskInfo[] var7;int var6 = (var7 = this.getTaskInfo()).length;for (int var5 = 0; var5 < var6; ++var5) {StopWatch.TaskInfo task = var7[var5];sb.append(nf.format(task.getTimeMillis())).append("  ");sb.append(pf.format(task.getTimeSeconds() / this.getTotalTimeSeconds())).append("  ");sb.append(task.getTaskName()).append("\n");}}return sb.toString();}@Overridepublic String toString() {StringBuilder sb = new StringBuilder(this.shortSummary());if (this.keepTaskList) {StopWatch.TaskInfo[] var5;int var4 = (var5 = this.getTaskInfo()).length;for (int var3 = 0; var3 < var4; ++var3) {StopWatch.TaskInfo task = var5[var3];sb.append("; [").append(task.getTaskName()).append("] took ").append(task.getTimeMillis());long percent = Math.round(100.0D * task.getTimeSeconds() / this.getTotalTimeSeconds());sb.append(" = ").append(percent).append("%");}} else {sb.append("; no task info kept");}return sb.toString();}public static final class TaskInfo {private final String taskName;private final long timeMillis;TaskInfo(String taskName, long timeMillis) {this.taskName = taskName;this.timeMillis = timeMillis;}public String getTaskName() {return this.taskName;}public long getTimeMillis() {return this.timeMillis;}public double getTimeSeconds() {return (double) this.timeMillis / 1000.0D;}}}

【2】StopWatch优缺点:

优点:
1.spring自带工具类,可直接使用;
2.代码实现简单,使用更简单;
3.统一归纳,展示每项任务耗时与占用总时间的百分比,展示结果直观,性能消耗相对较小,并且最大程度的保证了start与stop之间的时间记录的准确性;
4.可在start时直接指定任务名字,从而更加直观的显示记录结果。

缺点:
1.一个StopWatch实例一次只能开启一个task,不能同时start多个task,并且在该task未stop之前不能,start一个新的task,必须在该task stop之后才能开启新的task,若要一次开启多个,需要new不同的StopWatch实例;
3.代码侵入式使用,需要改动多处代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/701779.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL--索引结构

索引-索引结构 1. 概述2. 二叉树3. B-Tree4. BTree5. Hash 1. 概述 MySQL的索引是在存储引擎层实现的&#xff0c;不同的存储引擎有不同的索引结构&#xff0c;主要包含以下几种&#xff1a; 上述是MySQL中所支持的所有的索引结构&#xff0c;下面展示不同的存储引擎对于索引…

JDK下载安装

资源展示 安装说明 傻瓜式安装&#xff0c;下一步即可。建议&#xff1a;安装路径不要有中文或者空格等特殊符号。本套课程会同时安装JDK8 和 JDK17&#xff0c;并以JDK17为默认版本进行讲解。 安装步骤 &#xff08;1&#xff09;双击jdk-17_windows-x64_bin.exe文件&#…

【Eureka详细讲解】

Eureka介绍和使用 1. Eureka 介绍2. Eureka 的主要特点3. 使用3.1 设置 Eureka Server3.2 设置 Eureka Client3.3 Eureka Server 高可用配置 1. Eureka 介绍 Eureka 是由 Netflix 开源的一种服务发现解决方案&#xff0c;它是 Netflix OSS 套件中的一个组件&#xff0c;经常用…

8-pytorch-损失函数与反向传播

b站小土堆pytorch教程学习笔记 根据loss更新模型参数 1.计算实际输出与目标之间的差距 2.为我们更新输出提供一定的依据&#xff08;反向传播&#xff09; 1 MSEloss import torch from torch.nn import L1Loss from torch import nninputstorch.tensor([1,2,3],dtypetorch.fl…

(只需三步)免费使用知网的攻略

通过浙江图书馆可以进入知网&#xff0c;并且查看与下载都是免费的。 &#xff08;只需要三步&#xff0c;很简单的。&#xff09; 第一步&#xff1a;注册浙江图书馆账号 打开zfb&#xff0c;搜索“浙江图书馆”小程序&#xff0c;进入个人中心->办理读者证&#xff0c;…

不同尺度下的网络控制方式

《三国演义》和《长安十二时辰》有什么不同&#xff1f; 关羽败走麦城&#xff0c;远在千里之外的刘备收到两个信号&#xff0c;一个需要 “星夜驰援”&#xff0c;紧接着 “二弟休矣”&#xff0c;三国的故事在东亚大陆展开&#xff0c;地理尺度巨大&#xff0c;星夜不星夜其…

PHP语言检测用户输入密码及调用Python脚本

现在有一份计算流体力学N-S方程的Python脚本&#xff0c;想要在用户登录网站后可以可以运行该脚本&#xff0c;然后将脚本运行后绘制的图片显示在用户网页上。 建一个名为N_S.py的python脚本文件&#xff0c;这个脚本在生成图像后会自行关闭&#xff0c;随后将图片保存在指定的…

一篇超级最全的python基础篇

1.数据类型和变量 Python使用缩进来组织代码块,一般使用4个空格的缩进.使用#来注释一行,其他每一行都是一个语句,当语句以冒号:结尾时,缩进的语句视为代码块.Python对大小写敏感. 1.1 整数 Python可以处理任意大小的整数,包括负整数,写法与数学上写法一致,例如:-100.如果用十六…

【文本编辑器,哪款适合你?】讲解

文本编辑器&#xff0c;哪款适合你? 文本编辑器介绍 文本编辑器介绍 电脑使用者在选择文本编辑器时&#xff0c;应该考虑以下几个方面&#xff1a; 需求&#xff1a;你是需要进行基本的文字处理工作&#xff0c;比如写作业或者制作报告&#xff0c;还是需要使用到高级功能&am…

BIO实战、NIO编程与直接内存、零拷贝深入辨析

BIO实战、NIO编程与直接内存、零拷贝深入辨析 长连接、短连接 长连接 socket连接后不管是否使用都会保持连接状态多用于操作频繁&#xff0c;点对点的通讯&#xff0c;避免频繁socket创建造成资源浪费&#xff0c;比如TCP 短连接 socket连接后发送完数据后就断开早期的http服…

简单上手若依框架

简介 若依是一个基于SpringBoot&#xff0c;Shiro&#xff0c;Mybatis的权限后台管理系统官网文档&#xff1a;介绍 | RuoYi源码 前后端不分离 RuoYi: &#x1f389; 基于SpringBoot的权限管理系统 易读易懂、界面简洁美观。 核心技术采用Spring、MyBatis、Shiro没有任何其它重…

InfluxDB的常用数据操作

1.插入语句 # INSERT语句用于向数据库中插入数据点&#xff08;数据行&#xff09;。 # 这些数据点包含时间戳、测量&#xff08;measurement&#xff09;、标签&#xff08;tags&#xff09;和字段&#xff08;fields&#xff09;等信息。 # 以下是INSERT语句的基本语法 INSE…

C++面试:内存溢出、内存泄漏的原因与解决

目录 内存溢出&#xff08;Memory Overflow&#xff09; 内存溢出介绍 解决内存溢出问题的方法 内存泄漏&#xff08;Memory Leak&#xff09; 内存泄露基础 解决内存泄漏问题的方法 内存溢出&#xff08;Memory Overflow&#xff09; 内存溢出介绍 内存溢出是指程序在执…

第6.4章:StarRocks查询加速——Colocation Join

目录 一、StarRocks数据划分 1.1 分区 1.2 分桶 二、Colocation Join实现原理 2.1 Colocate Join概述 2.2 Colocate Join实现原理 三、应用案例 注&#xff1a;本篇文章阐述的是StarRocks-3.2版本的Colocation Join 官网文章地址&#xff1a; Colocate Join | StarRoc…

Rust所有权--与go对比学

如何拿返回值&#xff0c;如何不传递所有权就更改原值&#xff1f;如果想操作更改元变量要怎么做呢&#xff1f; 分别执行以下go代码&#xff1a; func main() {var a 10//calc1(a)//a calc_return(a)calc2(&a)a 100calc3(&a)fmt.Println(a) } func calc1(num int…

SQL Server 连接池相关内容

查看最大连接数 SELECT MAX_CONNECTIONS查看指定数据库的连接数 SELECT * FROM master.dbo.sysprocesses WHERE dbid IN ( SELECT dbid FROM master.dbo.sysdatabases WHERE NAMEDB_WMS_KZJ )获取当前SQL服务器所有的连接详细信息 SELECT * FROM sysprocesses获取自上次启动…

五大方法教你如何分分钟构造百万测试数据!

在测试的工作过程中&#xff0c;很多场景是需要构造一些数据在项目里的&#xff0c;方便测试工作的进行&#xff0c;构造的方法有很多&#xff0c;难度和技术深度也不一样。本文提供方法供你选择。 在测试的工作过程中&#xff0c;很多场景是需要构造一些数据在项目里的&#…

Centos服务器部署前后端项目

目录 准备工作1. 准备传输软件2. 连接服务器 部署Mysql1.下载Mysql(Linux版本)2. 解压3. 修改配置4. 启动服务另一种方法Docker 部署后端1. 在项目根目录中创建Dockerfile文件写入2. 启动 部署前端1. 在项目根目录中创建Dockerfile文件写入2. 启动 准备工作 1. 准备传输软件 …

全网唯一基于共享内存的C++ RPC框架

首先声明&#xff1a;我不是标题党&#xff0c;我是在找遍全网&#xff0c;没有找到一个基于共享内存实现、开源且跨平台的C RPC框架之后&#xff0c;才着手开发的这个框架。 项目地址&#xff1a;https://github.com/winsoft666/veigar 1. Veigar Veigar一词来源于英雄联盟里…

Nacos服务发现及其其他工具

1、什么是Nacos的服务发现功能 在微服务架构中&#xff0c;服务发现功能允许服务提供者&#xff08;服务实例&#xff09;将自己注册到Nacos服务器&#xff0c;同时服务消费者&#xff08;客户端&#xff09;能够通过Nacos服务器发现可用的服务实例。这样&#xff0c;服务消费…