29

这种方式更优雅,秒表计时

 4 years ago
source link: https://www.tuicool.com/articles/qyMjIzQ
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

7niqm2j.gif

你有看过学校百米赛跑时,体育老师手里的秒表吗?老师是怎么记八个跑道中的学生跑了多少时间的呢?

今天我们要做的就是实现老师手中的秒表,但是我们是没有办法同时跑N个任务的,只能一个跑完继续下一个。

许多人统计用时会向下面这样,但方式并不优雅!现在我们来一起实现一个秒表让统计更加优雅吧。

public class Test{
 
public static void main(String[] args) {
long s =  System.currentTimeMillis();
// 算法1
// do something
long s1 = System.currentTimeMillis() - s;
System.out.println("第一段代码执行时间:"+s1);
// 算法2
// do something
long s2 = System.currentTimeMillis() - s1;
System.out.println("第二段代码执行时间:"+s2);
}
}

看完这段代码就问你,烦不烦?

问题所在

那么我们烦在哪里?

1. 每次都要获取获取时间代码

2. 每次都要主动打印

3. 无关紧要的计时打印代码占据了视线

4. 如果n段代码统计对比,需要人工对比或硬编码对比

好了,问题知道了,来想想解决方案吧。

解决方案

1. 封装一个方法代替每次时间相减的代替

2. 将打印最后统一输出

3. 统计每段用时,排序或对比

开始实现我们的秒表类 StopWatch 吧

  • 每段计时任务要有一个唯一标识和一个最终用时

  • 需要一个容器来存储每个计时任务

  • 需要记录总时长和任务数量

具体实现

  • 每个计时任务类

public class Task {
private String name;
private long timeMillis;
 
public Task(String name, long timeMillis) {
this.name = name;
this.timeMillis = timeMillis;
}
}
  • 秒表类

public class StopWatch {
/*
* 存储执行或的任务容器
*/
private List<Task> tasks = new ArrayList<>();
/*
* 当前执行的任务
*/
private String currentName;
/*
* 当前任务的开始时间
*/
private long startMillis;
/*
* 总用时
*/
private long totalMillis;
 
public StopWatch() {
}
/**
* 开始任务
* @param taskName 任务名
*/
public void start(String taskName) {
if (currentName != null){
stop();
}
this.currentName = taskName;
this.startMillis = System.currentTimeMillis();
}
/**
* 停止任务
*/
public void stop() {
if (null == currentName) {
throw new RuntimeException("");
}
long spend = System.currentTimeMillis() - startMillis;
totalMillis += spend;
Task task = new Task(currentName, spend);
tasks.add(task);
}
 
public int size() {
return tasks.size();
}
 
/**
* 打印结果
*/
public void print() {
if (currentName != null){
stop();
}
StringBuilder s = new StringBuilder();
s.append("任务名称\t用时\t占比\t\n");
for (Task task : tasks) {
s.append(task.getName() + "\t");
s.append(task.getTimeMillis() + "\t");
double l = task.getTimeMillis() / (double)totalMillis;
s.append(String.format("%.2f",l)  + "\t\n");
}
s.append("总用时:" + totalMillis);
System.out.println(s.toString());
}
}
  • 那么看看现在如何做

public class Test {
 
public static void main(String[] args){
StopWatch stopWatch = new StopWatch();
 
stopWatch.start("任务1");
TimeUnit.SECONDS.sleep(1);
 
stopWatch.start("任务2");
TimeUnit.SECONDS.sleep(2);
 
stopWatch.print();
}
}

此时我露出了满意的笑容!

mmERnyr.jpg!web

最后告诉你个消息:Apache commons , Spring core , Google guava 都给我们实现了稍有不同的StopWatch类!

如果你跟随我一块实现了StopWatch,那去看看这三个提供的,应该 so easy!

fmaMJj3.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK